From 90647f30f856040c218b3605791c2bd96636ca0c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 20:54:06 +0000 Subject: [PATCH] Initial pointer adoption tests Have instances actually dispose of their held C++ objects! [SVN r12653] --- include/boost/python/class.hpp | 7 +- include/boost/python/class_fwd.hpp | 30 ++++++ include/boost/python/detail/cv_category.hpp | 34 +++++++ include/boost/python/detail/type_list.hpp | 16 ++++ include/boost/python/detail/unwind_type.hpp | 51 ++++++++++ include/boost/python/manage_new_object.hpp | 42 +++++++++ include/boost/python/module.hpp | 3 +- include/boost/python/object/class_object.hpp | 26 ++++++ include/boost/python/object/class_wrapper.hpp | 8 +- include/boost/python/to_python_owner.hpp | 93 +++++++++++++++++++ 10 files changed, 300 insertions(+), 10 deletions(-) create mode 100644 include/boost/python/class_fwd.hpp create mode 100644 include/boost/python/detail/cv_category.hpp create mode 100644 include/boost/python/detail/type_list.hpp create mode 100644 include/boost/python/detail/unwind_type.hpp create mode 100644 include/boost/python/manage_new_object.hpp create mode 100644 include/boost/python/object/class_object.hpp create mode 100644 include/boost/python/to_python_owner.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 0f8d2a69..b63236c8 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -6,6 +6,7 @@ #ifndef CLASS_DWA200216_HPP # define CLASS_DWA200216_HPP +# include # include # include # include @@ -14,7 +15,7 @@ # include # include # include -# include +# include namespace // put some convenience classes into the unnamed namespace for the user { @@ -80,8 +81,8 @@ namespace detail // template < class T // class being wrapped - , class Bases = mpl::type_list<>::type - , class HolderGenerator = objects::value_holder_generator + , class Bases + , class HolderGenerator > class class_ : private objects::class_base { diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp new file mode 100644 index 00000000..6faf7aae --- /dev/null +++ b/include/boost/python/class_fwd.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_FWD_DWA200222_HPP +# define CLASS_FWD_DWA200222_HPP + +namespace boost { namespace python { + +namespace detail +{ + struct empty_list; +} + +namespace objects +{ + struct value_holder_generator; +} + +template < + class T // class being wrapped + , class Bases = detail::empty_list + , class HolderGenerator = objects::value_holder_generator + > +class class_; + +}} // namespace boost::python + +#endif // CLASS_FWD_DWA200222_HPP diff --git a/include/boost/python/detail/cv_category.hpp b/include/boost/python/detail/cv_category.hpp new file mode 100644 index 00000000..f4ac4b92 --- /dev/null +++ b/include/boost/python/detail/cv_category.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CV_CATEGORY_DWA200222_HPP +# define CV_CATEGORY_DWA200222_HPP +# include + +namespace boost { namespace python { namespace detail { + +template +struct cv_tag +{ + BOOST_STATIC_CONSTANT(bool, is_const = is_const_); + BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_); +}; + +typedef cv_tag cv_unqualified; +typedef cv_tag const_; +typedef cv_tag volatile_; +typedef cv_tag const_volatile_; + +template +struct cv_category +{ + BOOST_STATIC_CONSTANT(bool, c = is_const::value); + BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); + typedef cv_tag type; +}; + +}}} // namespace boost::python::detail + +#endif // CV_CATEGORY_DWA200222_HPP diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp new file mode 100644 index 00000000..66ac3857 --- /dev/null +++ b/include/boost/python/detail/type_list.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TYPE_LIST_DWA200222_HPP +# define TYPE_LIST_DWA200222_HPP +# include + +namespace boost { namespace python { namespace detail { + +struct empty_list : boost::mpl::type_list<>::type {}; + +}}} // namespace boost::python::detail + +#endif // TYPE_LIST_DWA200222_HPP diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp new file mode 100644 index 00000000..eb103be4 --- /dev/null +++ b/include/boost/python/detail/unwind_type.hpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWIND_TYPE_DWA200222_HPP +# define UNWIND_TYPE_DWA200222_HPP + +# include + +namespace boost { namespace python { namespace detail { + +template +inline typename Generator::result_type +unwind_type_cv(U* p, cv_unqualified, Generator* = 0) +{ + return Generator::execute(p); +} + +template +inline typename Generator::result_type +unwind_type_cv(U const* p, const_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type_cv(U volatile* p, volatile_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type(U* p, Generator* = 0) +{ + typedef typename cv_category::type tag; + return unwind_type_cv(p, tag()); +} + +}}} // namespace boost::python::detail + +#endif // UNWIND_TYPE_DWA200222_HPP diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp new file mode 100644 index 00000000..1c41a75d --- /dev/null +++ b/include/boost/python/manage_new_object.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MANAGE_NEW_OBJECT_DWA200222_HPP +# define MANAGE_NEW_OBJECT_DWA200222_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct manage_new_object_requires_a_pointer_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python_value; + +struct manage_new_object +{ + template + struct apply + { + typedef typename mpl::select_type< + boost::is_pointer::value + , to_python_owner + , detail::manage_new_object_requires_a_pointer_return_type + >::type type; + }; +}; + +}} // namespace boost::python + +#endif // MANAGE_NEW_OBJECT_DWA200222_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 3a243b06..1d4fdd6d 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -12,11 +12,10 @@ # include # include # include +# include namespace boost { namespace python { -template class class_; - class BOOST_PYTHON_DECL module_base { public: diff --git a/include/boost/python/object/class_object.hpp b/include/boost/python/object/class_object.hpp new file mode 100644 index 00000000..76960762 --- /dev/null +++ b/include/boost/python/object/class_object.hpp @@ -0,0 +1,26 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_OBJECT_DWA200222_HPP +# define CLASS_OBJECT_DWA200222_HPP + +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct class_object +{ + static PyTypeObject*& reference; +}; + +template +PyTypeObject*& class_object::reference = converter::registry::class_object( + converter::undecorated_type_id()); + +}}} // namespace boost::python::objects + +#endif // CLASS_OBJECT_DWA200222_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 4a52f290..f8702205 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -25,9 +25,9 @@ struct class_wrapper static PyObject* convert(T const& x) { - // Don't call the type to do the construction, since that - // would require the registration of an __init__ copy - // constructor. Instead, just construct the object in place. + // Don't call the type directly to do the construction, since + // that would require the registration of an appropriate + // __init__ function. PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0); if (raw_result == 0) @@ -37,8 +37,6 @@ struct class_wrapper // exceptions. ref result(raw_result, ref::allow_null()); - ((instance*)raw_result)->objects = 0; - // Build a value_holder to contain the object using the copy // constructor value_holder* p = new value_holder(raw_result, cref(x)); diff --git a/include/boost/python/to_python_owner.hpp b/include/boost/python/to_python_owner.hpp new file mode 100644 index 00000000..7d3ee5ae --- /dev/null +++ b/include/boost/python/to_python_owner.hpp @@ -0,0 +1,93 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_OWNER_DWA200221_HPP +# define TO_PYTHON_OWNER_DWA200221_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +template +struct to_python_owner +{ + static bool convertible(); + PyObject* operator()(T ptr) const; + private: + static PyTypeObject* type(); +}; + +// +// implementations +// +namespace detail +{ + struct make_owning_holder + { + typedef objects::instance_holder* result_type; + template + static result_type execute(T* p) + { + return new objects::pointer_holder, T>( + std::auto_ptr(p)); + } + }; + + struct get_pointer_class + { + typedef PyTypeObject* result_type; + template + static result_type execute(T* p) + { + BOOST_STATIC_ASSERT(is_class::value); + return python::objects::class_object::reference; + } + }; +} + +template +inline bool to_python_owner::convertible() +{ + BOOST_STATIC_ASSERT(is_pointer::value); + return type() != 0; +} + +template +inline PyObject* to_python_owner::operator()(T x) const +{ + PyObject* raw_result = type()->tp_alloc(type(), 0); + + if (raw_result == 0) + return 0; + + // Everything's OK; Bypass NULL checks but guard against + // exceptions. + ref result(raw_result, ref::allow_null()); + + // Build a value_holder to contain the object using the copy + // constructor + objects::instance_holder* p = + detail::unwind_type(x); + + // Install it in the instance + p->install(raw_result); + + // Return the new result + return result.release(); +} + +template +inline PyTypeObject* to_python_owner::type() +{ + return detail::unwind_type(T(0)); +} + +}} // namespace boost::python + +#endif // TO_PYTHON_OWNER_DWA200221_HPP