From 9923a4c4ff81a150fa5367cccd1b392908afe54e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Jan 2002 06:47:22 +0000 Subject: [PATCH] More "realism" [SVN r12239] --- include/boost/python/converter/class.hpp | 18 +++---- include/boost/python/object/class.hpp | 53 ++++++-------------- include/boost/python/object/value_holder.hpp | 12 +++-- src/object/class.cpp | 29 ++++++----- 4 files changed, 48 insertions(+), 64 deletions(-) diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index c6fef86a..458ecee4 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -32,31 +32,31 @@ struct class_unwrapper template void* class_unwrapper::can_convert(PyObject* p) const { - return objects::find_holder(p); + return objects::find_instance(p); } template -T& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T& class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast(found); } template -T const& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T const& class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast(found); } template -T* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T* class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast(found); } template -T const* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T const* class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast(found); } }}} // namespace boost::python::converter diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index b272d5fe..bc8f40d1 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -17,15 +17,16 @@ namespace boost { namespace python { namespace objects { template struct holder; // Base class for all holders -struct BOOST_PYTHON_DECL holder_base : noncopyable +struct BOOST_PYTHON_DECL instance_holder : noncopyable { public: - holder_base(converter::type_id_t id); - virtual ~holder_base(); - virtual bool held_by_value() const = 0; + instance_holder(); + virtual ~instance_holder(); - holder_base* next() const; - converter::type_id_t type() const; + // return the next holder in a chain + instance_holder* next() const; + + virtual void* holds(converter::type_id_t) = 0; void install(PyObject* inst); @@ -39,41 +40,30 @@ struct BOOST_PYTHON_DECL holder_base : noncopyable }; typedef iterator_adaptor< - holder_base* + instance_holder* , iterator_policies , value_type_is - , reference_is - , pointer_is + , reference_is + , pointer_is , iterator_category_is > iterator; private: - converter::type_id_t m_type; - holder_base* m_next; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform -// way to get a pointer to the held object -template -struct holder : holder_base -{ - typedef Held held_type; - holder(); - virtual Held* target() = 0; + instance_holder* m_next; }; // Each extension instance will be one of these struct instance { PyObject_HEAD - holder_base* objects; + instance_holder* objects; }; -BOOST_PYTHON_DECL holder_base* find_holder_impl(PyObject*, converter::type_id_t); +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t); template -holder* find_holder(PyObject* p, T* = 0) +T* find_instance(PyObject* p, T* = 0) { - return static_cast*>(find_holder_impl(p, converter::type_id())); + return static_cast(find_instance_impl(p, converter::type_id())); } BOOST_PYTHON_DECL PyTypeObject* class_metatype(); @@ -82,22 +72,11 @@ BOOST_PYTHON_DECL PyTypeObject* class_type(); // // implementation // -inline holder_base* holder_base::next() const +inline instance_holder* instance_holder::next() const { return m_next; } -inline converter::type_id_t holder_base::type() const -{ - return m_type; -} - -template -holder::holder() - : holder_base(converter::type_id()) -{ -} - }}} // namespace boost::python::objects #endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index a06afe84..be7247da 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -7,11 +7,12 @@ # define VALUE_HOLDER_DWA20011215_HPP # include +# include namespace boost { namespace python { namespace objects { template -struct value_holder : holder +struct value_holder : instance_holder { // Forward construction to the held object value_holder(PyObject*) @@ -58,8 +59,7 @@ struct value_holder : holder : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} private: // required holder implementation - Held* target() { return &m_held; } - bool held_by_value() const { return true; } + void* holds(converter::type_id_t); private: // data members Held m_held; @@ -75,6 +75,12 @@ struct value_holder_generator }; }; +template +void* value_holder::holds(converter::type_id_t x) +{ + return x == converter::type_id() ? &m_held : 0; +} + }}} // namespace boost::python::objects #endif // VALUE_HOLDER_DWA20011215_HPP diff --git a/src/object/class.cpp b/src/object/class.cpp index 1b855120..8e85f38b 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -11,13 +11,12 @@ namespace boost { namespace python { namespace objects { -holder_base::holder_base(converter::type_id_t id) - : m_type(id) - , m_next(0) +instance_holder::instance_holder() + : m_next(0) { } -holder_base::~holder_base() +instance_holder::~instance_holder() { } @@ -134,28 +133,28 @@ BOOST_PYTHON_DECL PyTypeObject* class_type() return &class_type_object; } -void holder_base::install(PyObject* self) +void instance_holder::install(PyObject* self) { assert(self->ob_type->ob_type == &class_metatype_object); m_next = ((instance*)self)->objects; ((instance*)self)->objects = this; } -BOOST_PYTHON_DECL holder_base* -find_holder_impl(PyObject* inst, converter::type_id_t type) +BOOST_PYTHON_DECL void* +find_instance_impl(PyObject* inst, converter::type_id_t type) { if (inst->ob_type->ob_type != &class_metatype_object) return 0; + instance* self = reinterpret_cast(inst); - holder_base::iterator match = std::find_if( - holder_base::iterator(self->objects), holder_base::iterator(0) - , bind(std::equal_to() - , bind(mem_fn(&holder_base::type), _1) - , type)); - - return match != holder_base::iterator(0) - ? match.base() : 0; + for (instance_holder::iterator match(self->objects), end(0); match != end; ++match) + { + void* const found = (*match).holds(type); + if (found) + return found; + } + return 0; } }}} // namespace boost::python::objects