From a75ee50533e173dcc92a9fd3eba2518df37b7dfd Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sat, 21 Sep 2002 02:50:29 +0000 Subject: [PATCH 01/83] 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 02/83] 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 03/83] 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 04/83] 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 05/83] 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 06/83] 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 07/83] 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 08/83] 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 09/83] 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 10/83] 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 11/83] 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 12/83] 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 13/83] 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 14/83] 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 15/83] 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 16/83] 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 17/83] 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 18/83] 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 19/83] 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 20/83] 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 21/83] 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 22/83] 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 23/83] 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 24/83] 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 25/83] 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 26/83] 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 27/83] 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 28/83] 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 29/83] 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 30/83] 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 31/83] 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 32/83] 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 33/83] 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 34/83] 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 35/83] 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 36/83] 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 37/83] 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 38/83] 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 39/83] 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 40/83] 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 41/83] 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 42/83] 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 43/83] *** 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 44/83] 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 45/83] 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 46/83] 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 47/83] 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 48/83] 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 49/83] 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 50/83] 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 51/83] 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 52/83] 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 53/83] 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 54/83] 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 55/83] 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 56/83] 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 57/83] 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 58/83] 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 59/83] 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 60/83] 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 61/83] 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 62/83] 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 63/83] 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 64/83] 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 65/83] 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 66/83] 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 67/83] 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 68/83] 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 69/83] 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 70/83] 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 71/83] 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 72/83] 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 73/83] 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 74/83] 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 75/83] *** 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 76/83] 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 77/83] 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 78/83] 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 79/83] 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 zcmZ?wbhEHbWZ+<8_|5Qs zOXn|KICuX1*>mU4oIQK`%$bv?P8~mS;_#6p2M--OaPZ*2|Ns8}`}_OP@1MVZe*f|P z>$k6;zkL4q>Ertk?_a-p{qohz=P#Z=efIS6lgAGqJ-mDG?(I9bZ{E6j{l@jH*REc< zdgbz!%NH+QJb&T**>h)4pE-T<)X5VkPaHpS{OGZxhmRaScdEzI5s0g$w7;ojZHx%;{67PM$b%{MfOhM~)mmbm-u}zkmPy{{8Fc z&mZ5vfBX9N%jeIZK7Rc8;lqdb@87+B`{woQS1(__c>es^)2C0LJbCi?@#9Azd+y!6 zd*}A;TQ_gsxPJZG)vH%7U%qtl;>8OWE}TDq?(Eq!r%#_cdGf^Z(|epKfinT?$xVT&!0cPfB*i?n>VjryLRc)rPHTRA3uKl*s)_rj~+dA=+MD~ z2mk;74@!aqhZTRaFfuS)WzYdTfrE*Gf#W{|D~F87h6M+kIfS)hPHb3sxSew)=K?q1 zo*A7Y+G%$@bUlvuDjn(&P-&9#40Lqr;xS&kbj37-WTr+*jb|nb#)Z$WoGg|QnD4;E z$}7m_(UGXw(-v`R%gZ2x1SgMZtI$;@2A4Kv-JK;Wppa?5sfp?1;y3&b7cVt+vFWaj z&d7bZX)5=2y*u^=wGO|(EX?0vU(3w>&A4KNyuGc!_lP^`h5Y<|jg_As9qe9ye4b6l zwLfQ^)Ai5qX{dACwdG~H&Ag8<4?GTEepS}0bcXM2GjToHy!Q__EjE9D&${OA%e|@W z?0kFswd2>dHcxwYZtIH)da>=LulJU`xVUlQ?(e*_H|6|)aMau8C$Hs+$^PfH-TQ1R z@9Zys?=x8~Jz~zw`|IWT`TqZVsPLeHC2azu+{_n~4vNl9xsbqCE>UruSHP*_aH~Yx zjBZ);8;P!ZJ54V0s3}d$NHR8C5Yf)7bE~1dTQ989TQ>AY!NFdOXC2DM;s%c&_d8rV z$RjEy66rkABPywrb=n1o!;{1;ZZ4VZcg~QVS2QKkQ8hZvvUQqhfWosGDbqY1b%i@T zJ$0w}Ja{%+SVuX1PT{G{<#UBjZ0KRB_A~MnG4fDY!7@oii*sS?F$GVa9y2Ls-9i@! zZ=Q*62``rlo-yL)nd4^Ey?kEYDNUY&1B}f&0S6cuRaQGa$kJKA>;Eq%7X2ehueoCC=QUEHU3eC%TOvq*Tmm2XSK+O4`Jr=7U( zZ&FydBX>tq9`hr!NoRJw*|ghfxAqb3_gpz=ZgVO7Y&gikymrlj6Z;tS4>lZN(O=kf zP)lWvfi~CbhBJrxwHZGi;a@(1$w(|Y=i{-}Yc{nVm0!M~Ly3DzjuDsY>P4TJJXfqS z;xahAhV9JC3u_pJvNRTKKG*rC=8T~^^WV>g9z3~U3|A=BI!SdbC~{)rlxgI+5)z(! z=4wFv+OOB57cVqrIwsM0KykT(f*DhWazVqb?9F?>F%}%x{mz&^qo{$?RU)ZLQ|-?G zTnEFpKe1;Xw1~&~a5gKitKjT0kMrV8Gl+9w?3o?NAUHkQZs)UE{&p^m^Cy4!DX?fV zgB9nB$$h_Gtq^Xgl62Y<$HAF8L5YQtMWo33-5%j4YenS`ayE?00!e>3jw-MJ^XW8y z!ygT0hxdONnic$c44Wqe{{4ES=fL0Z4~pdvd}W;Ce@23FLHxg8uhzf+_xr>dZ0q&_ro_$*)&KXHJ~>O-SIO9zX($3d>B4+=tp z9&GGMf_)VqnxzF2~2bDEV-EKv2bxY*UR~f7&IJR9RnsyOkok(ddc;Axj;dB?G%OglF%;MDPOi~D?QUFpVyv9A|h z-}B@si`tq7#+)DGNi!KXG;qF2@a}kXP|7V*RfR{=E8>Wf#<827wLZzxk8fxNZDLf5S`-*g1G-<_FP%4WjK(VO8e9VOK_kzu*20`H0i zw>bMIw5_uIp5=Zas$^%`)?kUpBJDfY-Q3o_ZSzvy++yzhJ8!O;Gs_&hbMvQ zpya!~X&!SPDP7<3OK2fW|KgaZUKcD+PhC_zpZV^KHUle0VT;nG$+E9cIWPsC>0@x( zAlp)Yd^eZyf%0RAKYZvbPkf-tUnv)NPh-JxnnTmUv3TtYXDw-J(~ak 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 zcmZ?wbhEHb6krfw*vtR|#>U2JX=yW!8D`F$dFITS|7mIeXEOYsnf8C?%>QSM|DT!p z|3Ab3|7ZS#f#OdVMg|6c1|5)2kQodtE+0;Mrh1v)&NktlbFtDxn8UO z;r-;j1{PAOtmhI`^ZQ$`?Vo5^lJnE)FXOS;BTSwwM;uJF`-&nQOeQ$%aW%bBZ0PX~ zw?1)4NaCVuyTUWY_6oNJOeY#9C5W%N$M~d2FG!|%fxYtTwG$?`1RTjRk;>cDnZ+Oa z{_E=N>sPH_^}4>^oA>Hw^fD{QFP6dd8{E z5?+0_u<@X?i&Ps^Y7%ElZ_}=>OMA94uhmL45D@LZ>prE+EN{X6wcV?j7#R*-mui*g zvpDAvV$;TSHnm5Z!SvqJ_Sg{VhwVjk7Ea4vdAUy@Z`$$Q>t63z_j*dPX`ueoAGIN+ zxhC??jY*NKm=#{=6=m&GVOW)P<3Nc()yk$scMgAs!*i!Jzgzd(%Bdq(@krjy-uK>4 z7V!*am*b=vcC33HT9`Y9@3@FYm;^_V^6wA5*=urY7V9M{teEhv@ndVt{cawXzs39B z=kHkeTC_ITNZ?XjbVcnvfuvvWHDBJ+unpr%QC)Ob*wxQi_g34te|c{fTOHtGVGuZ= z@NV55F%E`+W3f9WIX)D(wM(cVvC2IsIZaH=6;Fgb*j9Vv^^EP)#2E;B~tN)C( zNk#g;N#lZj=?9OM$0^LX&US{sWzo9cPl*}w!ZDOgmT1B zo(0v36U_uvU=G7LhFszt=4M} zyll)o?T1^X@{Si8NVweIb1$(udv|W7u1Uq$;){(84C?B_HXHWN zeOaB8&DzDsvS3H{;v_>64X4|;lrEjufB)!tsp!(gGS1YOYNvi#8OiYUa<>^VIYw>y zsH-fX!sh(hK*Xa{+WJH7{tde;7+P7p#rhtbSV^4XVbRQg{9C>6@ibA6OD9jVd{6oF z+iN#p^QL4CfrcLr8%&n9UPu=TRaBFhGS2>xSJh`?*LfpssZ6cTy{Ut2=m=#^#L|?t@X14D2tb-Ri@;cO54>RAs&C{ZK zEFdCJuV-J*PCEtd@czHENB!lsW`VDBxD%?5hyi=Q^2m&b5lg%*ep`I7u1~CgU|rAs=f&@X^~R@eFP-YraYFBQZ`8+_XC?uc*Vf51 zNN}(;EZi_9$9m$k+!AH&DY~JJQ+e2;Enb}excI&MzvwGn=_^kzWC)Sw2~AMg!o0hG zn$Hbiqs<1n4;>g5HGVjEpQ--K>jU}Un$2$>IDLF>t^j|!)OGF~Y{TZST4noPiTTMS z%j#7p-Aj&T1{oL#>}uAYHN9ou+M@*)Iwk%KPn=39p51-_&F%e~Z(pT9uI!4snv?V3 z`i`q-BCqWIG_&!7E~rwPnDub({<(TV-jkMUYrL7Ir6r&f+O+$_gr8;@mRp@msW;IanJKJ*JKW4JXFtZuxe^-yx<$N$E|h3@mML|cRgRv zhVH3*s`0}iOmv&1hns5P5xteu93-~y^}1mD`1id&0p-LsQTpC}$|lEoTAn?gacI(o z<04)6azoNHE2b{LD|c?q+6T9uF3vPK6L@9ou65lPGnQ%G$au_9Jjd#o*uC4g4y8Z5 zc004>;Dae;j#~`c4o%|l7Z1K%cIwC8>Ur$fOVhV4d@(or;IE^hb0VVy=ik0>eeCo* z$48&1hRAyGv@{t=>}pNsI(@jiCZJ&HgI#)NW@c$jiM7R|;%<9A6c`T7+$w7G_FK~Y zdu&tc(fo^=7G` zws4NyTYT`VOpHBSQ`W(Y`{maCDr+e73C;~t@Zf3tmaI|I63O{vpZ=lq)*NBR>Uzw6 zo5h1>S${CO>Nw}`-sC-XKRwKDwO({SwZcc~YExyNsnnhoYdb;3^R3>67m5md_la@M z`?=LK2b2iGjcF1CTHmA6L%GA6d{j-0!7;_JE52U{M`omy%Azny|NeV%hrV#m^62pHr%w1`)XVG_wT0FY!0uEh1K={*|%nM&!t^u zKQ)Scf4x>~ouT{ZQN~rL6bDN+kz+H;uAV&;qZK@x*)hpr3%m0|)}XS?6>Yxtdv4~Y zcwLUq4^I0o$gpQeC9}gWhtt)uzf2$G=MR5mrP ztBP?n65lRrdQ4GUNFn2oZesN5sMb|Xj(PQe4}3H8OS`cuNsy;4Em>pBjE!uLZB4&g z&%L(ta(*ATN?V|0+q-qHtJsxuz7#Sud=23YWp6r?pwO`JLe{a^wJ~{X-WA=xQyQYW zH_9MnpM6j)$hjT6mu#DHaqYtcGZr3ki12u7z4DqY2g8TWYjy9Ox)7k>w0pIgu=B#d zPu7)8%en=T+w&UjHDyaP|H3Cffvxy7vn)NpQ_QqNON(`uyqDpT6q< z*cY7kc(%Gg&HeiYvDdRdZJk==cqHJ3ROJL7-6N}iv7XMV>CPybU6UJP)8=&iOIDow zg)p}nR;4k{7kl$3_U27q-`jOG;Dtn)?99I*~ejwP~Pl*}=lB@1<==bh8c0H$L>5^mHUx3ZLS@`%DTAn<`Rnl79Kc zZ*qUW0q@s@|WXPa*@w$WIlXuo+| z)AiTySAE)4ci7v>LZAELewCKV->PG-f4vdw13(d5*p+HJy@pRqRE-DZ2BnRLa5r!`N4QDf0n>PAq9ji!qo1N}MY^CAegTuHSeDD$Fc5q+eWh@S1Asq=Uik z7E9*doBhlu)mY*YlVg%WK(K+xu7ldYIM1(HyM#}&xGZRn$mFrpU#``0Z>OkD{nLdW;=z-+7sov+ zT)4Mb+hX&!pqCDt#X|1wIiAMJ@{;?&yOZ<(*W@X9@UX3t7GGc55_4eNzMWAw9M6ZJkx9leeyIXkB`#W5EJylt!vM2uUTk_gt_g2?=4j1-r-`aZq*WWAs-)rmN>{>VZ z``3<7NlP!tCNH>=H~qNYx<%W!HO)=jrn%hn+xNbU(cDZAGPk#XJsS!t-w$cLXj+vu z_t3w48|@Cvv3Q+v(Sf0Xef##p=P8qZeOx24LT`gP(uJp^;kWF3}e(u}@jT1*ea_RrT8aLW4_?j&+F;KhuBvxnFkoYHwq8~=UYz{@Sf!DZlXJxG-Gg6-ad-AyytR?dR)DS9amng6UOX(XnA#2r8SL(Rw5RUriqMA} z_KUa7wbQUfBfp-apUuf?77v?!!ATeXC4W=^XuAm-vbT{)+H{zp!iGCx+wQhg$ud3F?X?OyQyY7KZr5pH2#8yH zz+r)2($WjMeg7JHSQw;>!Y1hoFg%Ek-zgsc-Tv6szx}DMj1gh3rzO1|K8m)~N!@PT z=;|uf_c$Uw@~^;w&8#u=`x+f$j|RNh$9w;~t>O_qfga@>EwLWS_rJ@&y_^?Odt&>E zMLU{bJ06xTXV-UD_MCU@{uiC5wt5@6<800oB{;66zOj2HP&>g=h4~<>LC=FsMD{x^X{FV%<;gx?&lZn@M>&yh&}GL@bHsF zYmVKGIiXI|9607*zG{E%xZx>*>#kR$qZ!w+ynnBF<5ZGvO?`55a$3zo4ol|5GY$*P z5;aO(ZdklFJ9K`xgTb^9YuDddy-$OE8lyt4!i|=x9x1C{e`vLHo36&t@b&DU$Go1& zqR$+@`wOlWJN3e8((Sx-PBz6O2TEhlm&Pvtz^$akxVzu#&<(w6mG>`Fr%#&Gq;=Ae zg<)M-;FH>1_Nc7}H4Eiqjx6Q8W*+W6`_!uSDbr$I?2npAEK%Cs-_WYXw*0_p1ufQa zlk$E!4n2ct)r{9dVtgzPrNO<=ZP#UNb9}RY;g6YaYJV5Z+mdoL;1sK%Xve|}vT{w0 zso}rpFuNQV`uE+wMujVmT-Qlc^(y^GnMBX6f0ORVUY;F4WhF6)`7aORAHR!8`u;&YYfN;?f$J@aqR~kVh;tpSl4JbZGo?S>FK&eOWCblp2o9R*|beQ z=n#7_;Dy4?QWa-M`IvR@S9NXOU*3~Fy_bKcc0r>+Z%q^4Iih@0oLG!}d_`EaE6!1n!8f5JaIpZ@;O z?v#DX@grT0w|W*{Fnm@fev4sq^w+IAT19uBtrT|Tuql$Vs8y;s@KV^(!{oxrlPvM& zv3D$IF8L?N#%#*yys%m(!D^lY|JjwRUuWFAcC&C@tX}CZADuGPQ1GHbn(lD*311|RyS|wZ#MYx zt)9*8K8x8tnLVi=?p+hJ<39W#Jvy3)O^MlgVfCDC``+!V;{cT_+t%+^jdyyIaqi>Q*)QgL+t1sufBD?Ye_9Mz{JF*M@IPgtXjA7w z2ayMg*1X>*37nHX7Q2Jvy5f(6x0v7W&w8#pyZvQ`_2NUNu|M|df4BS8m6dVExvVU{ zRz%u=@64ACvVRZA)cjt3SzqQJo1G2QzRw%}N|)QS*qFX8OY?P_<#54v!`|M>l2UJ6 zQ}&w4U2zV5(DkhCf>gbGM)}=%j~{Z3JasE0hNJmzh%s;~}>K6Di)q6AC_u z2z}Dv9di|YoHGOlASLSWt?p$>sV8zKkfprXR zNsZ4>>{@>Q<2SQkf9>qb<{UZRs<_cwsyC%P_}RK;I*&O8pUrBK5#wsPzq^ct8=DTrhiAyJxs}{Gc5h}Cy`K#;7(o}NryX^i0wu>b=uCVd6c1;mwTNc0bllhOS+V#TH zJfLAb{=EFr5N?=&_u%Q3>(mGv9zGu(Ber(yYxlifLM`lT(dw=TL1zMcMGNtdjHiL8@ z3eY&|?POu?R1tq+S=KaPe%6F4wPLBy$0U7MNyuJMm-|f$S*;Dw*Y*%FSLH1+sZNJAXyZlaqBgDMT>ENk3rzD<7$L|bpJ+zs_ zPiFGMgfRYPuFp=lhaO^>Q6}4~=Ue3KT6^m)>-#;m7QbD0K0W%4H{pj{fa#k$jz16X zo;W;5+Fhii`VU);8q@IaKd4N z{Blk(1)*A^hRzFB#W`B+lS?Cy z@#cKu(`%3Uc`l*xv#`%=@$lwIkDKD_dKsz>rd)k7>!5%*$0S`)>NDYKWxXQFv24jY zB}>!L`ZG<P9j{=?hT4WlhjtoJNpzv#N$v+Z`l>QeE4y6o?ka>mtupD)hGI`@|4*EgBJBhP$# zF!#WT@3q@Eh^t2h-TAH2zKq35tZM3p2M>%Eur|H1l8T-6;HUOa{(~EL8oXj%zA@JB z&_V5Kj4xi8?rPmFsuT9cBJaen)9L~cJ z9ipFzS#H~W;BRNgG+AfG=4Gr+Uv%DBFIy+s&nPAr!`8!?W;t)ezQ~yE6VJ}vI`zaa zc4d)0LGg1|Bsg&#|6aTP-Rlhx9g4ktd07;8MV$R(W5CoF#rDa>Q!|wVX^io`E9aZ(}>UV( zoS&Hdo}u7SvUz$0+jPd$TxsuLojtX?Pv>?{_0+u4G+@`;tdte*5vou4!@ zdG3x1UB}S7Zt~WC%k2IaY+aYm$FyIirI`J}tLuN>A2?>rxmhOWdTFb`<<<(qfKzyE2xvpBQiV|j{2#{6zkyXmW2o8Rud`uqvQ=8zPH z6AA{)W;2C1{a=&6Zq{SYxI}%wxzB&^OJ-?q&idaLWvF-3>)@g{d5aevUf`29)u3h} z|M%9qhqt5NfP3u+{vF-CyxI5Dna5VrHWBV;m!5ZVa=qFl^Cs``eQoE1i_T~*%sp;= z>zgGLL*XUuoak4^I9zs?}$1{PdyrzOYk|;Gg<=&;OUIpKiV#qRJ4n z+`xH?N&C*;#)Nb4%eF+iyXIsIzBKX@=D4_ai>2sPv4^M1KdsTpdzJM>X+zM3mQbgM zw3>o+d99b{=G%S)S6dEauiN{o;kO=@x2XCPK{+n zvPQtco~+9!fBls-yDq(D<)&1PDKGY}UAyM8U%FV|RoDN`)1y%G!mFN;00EQiYF*xv2WUie(y%X@e8`Kzs0jxwgVF*O~{a4&^LLuw2=lQIx&#x~i9g|GVPin)Q>v95riWb7njs%R0T$^^I55 z@*OKzxR%JuzL7nz=Qmk|g0CMfZHzUwKVO<(t8YttPo#>}^b^URs?}y7OS2 z=auux89WC1yVkZ!C2aG&o_l4>e9^7*)$eO={HXW3lKXgoMg;pYp*3Bzy0S`NxlFt1 zD!0JwlXBFIjYjuQ{`#A{is@3suK`!6h#t({)yS}ggPGxCT`MzD0T)+&=-CYm|SHmCEJH-5L@TCVuE zZbkh3dsm+?a!swgXmn=s_Z|LMV&pFMYo@%)%eyUc<5D{lS5C+#Hl_Yx$up#l)C}`5}o;9gVMd`AybdtCXoYp_C^_qvh6tRF*C47ivXUSViZi zo134!R4yM{xG5@nhP&9S*TP*={sEh(KRK29^5k!Z_lp-qbtJYqozQ)9NXmobA%|j& zVvBsPzQ^9wTF{$KU=r_ z;H}oT(g!~DdQ1-#iqsXUTWHGFe873b^ZJ?P>y2b;6kE2xQGED&-|4()cSifx3<6?4_wsY6LsugKD{Gs00oLtBfH` zpt5w;?apMbC9^F9+_gUGJTuPLuDJD_@hh@d1t}4pcl3sMXXHIh1uU_rVXJ zMH_be?OV#t_%|cy`MsO#zx$u-JH6-s%QtVapKDL8g!sNsJ5DVW zXnLNgeA(o|wItBA?pIFNdB=0CHg9YCdiLrAz8}ZsS$Jdbh)HOg?BqVl(;T9>!19JQ zTfy@$!pr@RtpDzjT$KH5bKR4YSzTv%`PY2^v_C`LqBP#&=CrB>I~nKf(m$}QC(^x8 zZugF^<##t^znXm8@$r)Vr4BcEg;(dD~K7STRkr5vh5% zW9F$v){B=FrscBs$Hw&TiIwnW-+sA;=|Yd_qbP|tPW&yKmp9)G?VrOoZwEj7_5O|f z%jf*-JbTKM&+7k!yI;-=2CL2h`Rn<58x!Gk3sZU7mcQd(aVV&ri7QUMpnv+`m$NQ( zsA@j)dFGlD>ls_VHG!AeQ(m9*{g&-$oYpfpBikSScuQ2D}xPALuuY$|IzgIJ_2UfhgyXV8y zyI#{03WEPKTP@k5`$W2FVZegPZ~0o??y;V9EuQy0anir%ucwq)8XsDxw3DlHRlU%S zDvldJiau-;eP{5y?BBuStwMi}%eyo`{L;B#;q=QPd;1sV*Z)6%!2VzK2Z_H&tSfo6 zE|m*LH6==fxzAk|?iyOM{95P2fDLP6Jxa^Vw{%WlT)occVeF@OXT;}JH@l|(YTEew zeV46=#@iiDtHc@>7@9LbJNdh*?S9SV#}dm71g^YUKjm7w^ie;#g#3ah*4NW^|B>4I z_wS-gY0`5wqzd8 zWTuUAv)P=c>H4gTwc`?#Iag#Y$K%XUc)8R%b*1yenL=WZp1g4?>e}0tbj9|B&dXRa z&E|uekFAo@MHw%@TU7GgNB_xBZGKL)MtdL^?iL+_yNyy-6w%>9tzxjwV~XhnE_+OF=khrWF?+qP|+(DD^xd;cjHu3z-; zTNN_Ux0KQ*CG};8Y=dv+DN5_cmpPSItiFYtrz>5(*t%tZxeaeiK{iM2$LY^2mxl1%s%n13eDHV1tquEXcid08h4cLSxTPq!Dc5Id_G}itT8$}&H*`u1TZ=_g;(s3e`uN2)0e`pi zu`_(sT783k=L9Z^`*7_~=;6Y;4|yf7#SyAoQq8>I^fu1PEd3uF%flAF@AB8JoV%9t zvo4rZ$f_`-^UASO?$UEsT|D#VSsC6=O+2wm_HB!hF#ef-P{Q7fNV-f&|(B>bIKyPrRQwU*-hhWx8ZQqI43b^m_P zwd+P&^FiH*mrgx7Rh}|cAXv9@YK(8I1eeBkZcYZdGdI5Lvd{J2IiqLJ=kjo~WdfNs zXJT#cTk=TFx@g|KJMgVuXqocPb+aY-9#%BAwQdi2&OzxPF7Obu<@-0x&(Ag226|K|hW z%<8sno%-uz>AF~n*jX-SM^|S>Wu*xC=l7(RcgsAPn$Gv#|J<8jnycBam;T+d{;zanUyYFRSNH z%PNySJA0Sr?~QY-gWC^Z&hwvZBKG{y3h_PLD%%?0ed&Cer1zPZ?@RhZ;9oD=l^z}aeV2P*C`lxUZA5)`siJO(p;@oM*=QPiPdE|%hzV{j{ENt+x)I_ zttuZCyPdYymyf1BK7Dy#PGw)CoX~PVhUI=KS#z$Nhc{oZ|84Ml+x1%yD&EKVd=HuZ z;-OBx`{d}Ges$fm?j~-F(`%Tyzki1GBEK?OMxNFVtyQcGE*@O)??Ue7pwsW1f{MTO zZf-W-{eRs{OEx2sl=41Fi{cf@n)^RmR>l9(+3~vm>Do+>8~5UVD^#4ZZhtX1IxsdQ z_uH1+v)hyf{^+E-Zg(&+N&OHxZ)q;~d$0TssfL9KD;7mDNXharG;9>)3N2B5YMH8Q zdb^TI@0Q?h+1^fA!q_nLL*LxK+ZR8wFbM3MUp492r5l2Ww2Rdyz1zE1w`SU>fGUO$ zwe>OAesVvnvp+2UYht8F`nB~_>yH0^^sINm#|wKuh5gf2tNWn$;pOworu_NxNq?p1 zZ{M%ITunc(t@(7izkBnwO@?v}FH2(XYUdxd{k!6n=Db9Kw@eSy8mAemeSL5GW8eL) za}z|vxWqz3xg9oNGnnz;xlhkmDgJ+N{O;wmB0aY4tFE-D6?Xk)*+j7>$ z+8sL8KL4@!|EKl|Uwi9kSN=XJFaPN1S?P+x&ur^r?YwqfKI_VRU>5ryo6MQ5OXsud zs`j7eS-nc?OYrBa=V5C^V-KBQxA`$AgLZ2~Xc)Icu@>9rs2jCk11)Z?dUkx@=gC3u zH(fOouiCoc{fU|16lQ<7pX)dC%KX<;w?|p(mZVoS-2bt)T4`#u(DzF$_pZ)fB^{7= z^@4VS`_=5}{fqv-*_L&{?YHfzHj7PbJ+E*ygn!|Y|NP$iWqx9MMMJw^ZRRrVt*1ko z4tObsO})x=VU8i&<|qU9IrFQ2h?5cKh8`4ma*w zAM2iN{^5E3506(43{8^B_g42G+W$1+hm*Xvd~M(L^(^k0dcS^GzezHP6SCBg;@fxo zT*n0F4{iz!myH#5q?!2yeWJgL?Yc1`_xtTib9TdSGwbcwCw5MCYFf3Lb%CU4^PEma z`)jLNzh7dh|218Hy4AJ?@8r%}2kgwBFlSMgHFqR`OR##{cmJyA1-n{Zo8P{deSD;S z{^Nzg@m`{A>n>hpKk%z|Q`3%*C-+DEzOZ@LN~vcN_hWk3nh39AQ^@GqyC#{h@Ojc1 z?w0K7{U5Fz-fwWZwX5s6?W+R;GZyzH?6~?q{gx0jL(TpB8mo#7{<}-f*)M%>b^ogM z*8Y1tul_GeUs-;~`Y^Lhjn1OmE*^=G`~IE0c{Ho&HK(z_p>^F$+*Wda``-8Q*HdMi zl2_gn=kN4mYq)1Cl3wudUFL#p#fPzbJA0Sk>yb@3TXnW5Eh@$#<>$`hvTK$|CjWag z|Hj?6%O&#rc2qJS{xCr^_WJHVhBhZHefHG!rBVVs6YDoyZVNc-qf#oK^-fV`rg7Y% zqnQ?^N@d5qC$DC?+5UFlh5kQl8gCjl?O}WVzRzZV`B$|&-jfe$wJ$oeQc7%5dHl^2 zAEi&9-~Bn1=|F(TQ&q(|`d2pm+H@{q!_>R~blvy9kKNm8zwev>R2k-#QtZW2DN%_P zCR@EG{C6wnG7xBKT*|#zAZ`1D7nf4>0FO*}j&PN^r$QH59h3ZGd1uni3`_sLo$LQ!OX@y!X~JFMRoPB_a_6}@DxW-6 z-!6Um#>+{&y5=mu=MyaY;;zQTnN|#Pe7g3=V$z%soa%zr(yMy_;$N{0oTvJJ$hF9;;9Q_T%URFpAg}?t|y=Pbn*Fz zbM{wj9v4#a^E~^&srTvQ=G(Vt_I;ZY945}wHdEXrediQg*HHE4`m5He1x4JC$&FEX z!^6L(@qx`(HMh;>D=tYKXnX(r(Dz#N*MI(gsAg$$m^m}da$lA3x#0XmyQ_rH{oK9r z_p8MgJL-DoCR+ae<(c+x-V>ASGPf6}fBZFd@yv~L0+x%fo*AK;5_0`V)4Sy32aoqn z{`GO+`+mk9mB*wmg>c`yI{U`XsUK&YQdMQ2Jh$M0_>6lq)o*Ad3QliM&^_n#balDr z)r)hNs7bsCo)llHZDFn4%`>%WjnJNOdDG)U(^h#gL};djUG-b#`R=2Q&4k2_vjvhA zT5g=(Z0lyRL+t1GS-dlf|K-X2J%4_a-PfRr-4~wxXv`_O>pgjigGB4p#_%s+f9%uu zceve9sBW{%q)|9-^7mJZe|)yDSu(*jKXYZT;8|VIXSz{WZfbB`E1@9PQ7-v{uuEXYO*H;}mG zBlpiYm2qQ8I^STH9{pG3z{kN<2VMVzOsshItjQYhzPMRsK z?XNxYZpo(l@tRd)XYv#hc3ti4FBWwR*X}Mo zbI$D6ed}Wv|NrXQ+^ZwO#hPf~vi%^#GTub#^ZF;e^7ov1tDM6;2trlQ;D7) zF>~s}GmBhz?hln&++^_o-Xf^>x+SKG2YkLm4lYz=#V zpAq6%yN}!V^4u@G>%Tdw?oY1WohN*Yt`yP0E*W@#WZI7$p zuh@DzU|s2i#)LofBsj!)TDx?d%P;v0_887!zHlJNnd{8DH@UZFG*|XDzrC_)hC#%t zW5?e3U1GoU`jy|M<24c-Hw{Fzw(uNexRI{L`0ekchMNT$PG1+CFOh6>oKQ5oE6mqa zw<~w!Y|C>2SKnWmBX`EIB}alwG*CHG%`H|)H5)KpXE%kG`44nMs0R9WVY?CPWG zzrI}yx@@*Fd(x873!!HnCMW8x-ZjH(U2w9EYqG`_hx@f#-eqex+o8ch|MK zCE9m7{O{*y8qG|ouD1SGozuI)&+NqKz7=ogM$deA*uH%qLzV{r~iJ?M5! zVEg4&Yj&k1$A(-@(94pZvw!#J%T1?`1gx03)3r4Eto8N8xT_3D%C&EvSa3r7Wob~G z843`zAg*xZwsuq7uXFF(M^I7qs#^tE(D*3`~PR?6QWj4utdR!^DXUgtP z$G*N4_vN2nd6nbFj+AL?5=%_3&WjZE;M{Ls_BQoMK*o%1Er*rV_uULTq9z&Dbnx0; zIEeT;0r@v(7bf__4xZGy@^u6O<9fp;4^>6e}H7>jm;49k`XTTHl)|*f2 zTmIz}Q(y2jG2J{SRdQJT*T%bLRT3Mr*T?X*wq-k6Jh46d_S97Eb6;Oyx81Vf(?#9i zb-z+)h;yhWwoYeuUYJ_e^nd4^P0mXG0&m{F?fw4kTfyI7r3-e3I!OJR7n&1N#Id{Q zNwn}kv53D*j|60_+|X3e@WXiO<_W#^vy^QZuj)Qwbi6MRaQkk8?2Q8wTh<*k`};5S z$L8IcT?-vrFTUebWk0*aTjzGrx5VhW`wqLE4yL_iUoOcNBAL8EGNYbZNjFtv$;CzY zE$iDA+n7w9&crT1=lC_W{gu+?4X0N)n1)P$V>GK7yy4A1PI+|i+u+#o_s>3T!-O>j 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 80/83] 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 81/83] 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 82/83] 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 83/83] 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~