|
From: Jan G. <jan...@us...> - 2007-03-06 00:05:04
|
Update of /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv8179/boost/circular_buffer Modified Files: base.hpp debug.hpp details.hpp Log Message: Iterator invalidation made more explicit. Index: base.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/base.hpp,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- base.hpp 26 Feb 2007 22:37:08 -0000 1.81 +++ base.hpp 6 Mar 2007 00:03:46 -0000 1.82 @@ -60,7 +60,11 @@ http://www.boost.org/libs/circular_buffer/doc/circular_buffer.html */ template <class T, class Alloc> -class circular_buffer : public cb_details::iterator_registry { +class circular_buffer +#if BOOST_CB_ENABLE_DEBUG +: public cb_details::debug_iterator_registry +#endif // #if BOOST_CB_ENABLE_DEBUG +{ // Requirements BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); @@ -654,7 +658,7 @@ m_first = m_buff; m_last = add(m_buff, size()); #if BOOST_CB_ENABLE_DEBUG - invalidate_all_iterators(); + invalidate_iterators_except(end()); #endif return m_buff; } @@ -1061,7 +1065,12 @@ Invalidates all iterators pointing to the <code>circular_buffer</code>. \sa <code>clear()</code> */ - ~circular_buffer() { destroy(); } + ~circular_buffer() { + destroy(); +#if BOOST_CB_ENABLE_DEBUG + invalidate_all_iterators(); +#endif + } public: // Assign methods @@ -1896,9 +1905,6 @@ void destroy_content() { for (size_type ii = 0; ii < size(); ++ii, increment(m_first)) destroy_item(m_first); -#if BOOST_CB_ENABLE_DEBUG - invalidate_iterators(end()); -#endif } //! Destroy content and free allocated memory. Index: debug.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/debug.hpp,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- debug.hpp 26 Feb 2007 22:37:09 -0000 1.10 +++ debug.hpp 6 Mar 2007 00:03:46 -0000 1.11 @@ -22,47 +22,47 @@ // The value the uninitialized memory is filled with. const int UNINITIALIZED = 0xcc; -class iterator_registry; +class debug_iterator_registry; /*! - \class iterator_base + \class debug_iterator_base \brief Registers/unregisters iterators into the registry of valid iterators. This class is intended to be a base class of an iterator. */ -class iterator_base { +class debug_iterator_base { private: // Members //! Iterator registry. - mutable const iterator_registry* m_registry; + mutable const debug_iterator_registry* m_registry; //! Next iterator in the iterator chain. - mutable const iterator_base* m_next; + mutable const debug_iterator_base* m_next; public: // Construction/destruction //! Default constructor. - iterator_base(); + debug_iterator_base(); //! Constructor taking the iterator registry as a parameter. - iterator_base(const iterator_registry* registry); + debug_iterator_base(const debug_iterator_registry* registry); //! Copy constructor. - iterator_base(const iterator_base& rhs); + debug_iterator_base(const debug_iterator_base& rhs); //! Destructor. - ~iterator_base(); + ~debug_iterator_base(); // Methods //! Assign operator. - iterator_base& operator = (const iterator_base& rhs); + debug_iterator_base& operator = (const debug_iterator_base& rhs); //! Is the iterator valid? - bool is_valid(const iterator_registry* registry) const; + bool is_valid(const debug_iterator_registry* registry) const; //! Invalidate the iterator. /*! @@ -71,13 +71,13 @@ void invalidate() const; //! Return the next iterator in the iterator chain. - const iterator_base* next() const; + const debug_iterator_base* next() const; //! Set the next iterator in the iterator chain. /*! \note The method is const in order to set a next iterator to a const iterator, too. */ - void set_next(const iterator_base* it) const; + void set_next(const debug_iterator_base* it) const; private: // Helpers @@ -90,27 +90,27 @@ }; /*! - \class iterator_registry + \class debug_iterator_registry \brief Registry of valid iterators. This class is intended to be a base class of a container. */ -class iterator_registry { +class debug_iterator_registry { //! Pointer to the chain of valid iterators. - mutable const iterator_base* m_iterators; + mutable const debug_iterator_base* m_iterators; public: // Methods //! Default constructor. - iterator_registry() : m_iterators(0) {} + debug_iterator_registry() : m_iterators(0) {} //! Register an iterator into the list of valid iterators. /*! \note The method is const in order to register iterators into const containers, too. */ - void register_iterator(const iterator_base* it) const { + void register_iterator(const debug_iterator_base* it) const { it->set_next(m_iterators); m_iterators = it; } @@ -119,24 +119,17 @@ /*! \note The method is const in order to unregister iterators from const containers, too. */ - void unregister_iterator(const iterator_base* it) const { - const iterator_base* previous = 0; - for (const iterator_base* p = m_iterators; p != it; previous = p, p = p->next()); + void unregister_iterator(const debug_iterator_base* it) const { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()); remove(it, previous); } - //! Invalidate all iterators. - void invalidate_all_iterators() { - for (const iterator_base* p = m_iterators; p != 0; p = p->next()) - p->invalidate(); - m_iterators = 0; - } - - //! Invalidate every iterator conforming to the condition. + //! Invalidate every iterator pointing to the same element as the iterator passed as a parameter. template <class Iterator> void invalidate_iterators(const Iterator& it) { - const iterator_base* previous = 0; - for (const iterator_base* p = m_iterators; p != 0; p = p->next()) { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) { if (((Iterator*)p)->m_it == it.m_it) { p->invalidate(); remove(p, previous); @@ -146,12 +139,33 @@ } } + //! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter. + template <class Iterator> + void invalidate_iterators_except(const Iterator& it) { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) { + if (((Iterator*)p)->m_it != it.m_it) { + p->invalidate(); + remove(p, previous); + continue; + } + previous = p; + } + } + + //! Invalidate all iterators. + void invalidate_all_iterators() { + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) + p->invalidate(); + m_iterators = 0; + } + private: // Helpers //! Remove the current iterator from the iterator chain. - void remove(const iterator_base* current, - const iterator_base* previous) const { + void remove(const debug_iterator_base* current, + const debug_iterator_base* previous) const { if (previous == 0) m_iterators = m_iterators->next(); else @@ -159,23 +173,23 @@ } }; -// Implementation of the iterator_base methods. +// Implementation of the debug_iterator_base methods. -inline iterator_base::iterator_base() : m_registry(0), m_next(0) {} +inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {} -inline iterator_base::iterator_base(const iterator_registry* registry) +inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry) : m_registry(registry), m_next(0) { register_self(); } -inline iterator_base::iterator_base(const iterator_base& rhs) +inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs) : m_registry(rhs.m_registry), m_next(0) { register_self(); } -inline iterator_base::~iterator_base() { unregister_self(); } +inline debug_iterator_base::~debug_iterator_base() { unregister_self(); } -inline iterator_base& iterator_base::operator = (const iterator_base& rhs) { +inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) { if (m_registry == rhs.m_registry) return *this; unregister_self(); @@ -184,42 +198,26 @@ return *this; } -inline bool iterator_base::is_valid(const iterator_registry* registry) const { return m_registry == registry; } +inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const { + return m_registry == registry; +} -inline void iterator_base::invalidate() const { m_registry = 0; } +inline void debug_iterator_base::invalidate() const { m_registry = 0; } -inline const iterator_base* iterator_base::next() const { return m_next; } +inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; } -inline void iterator_base::set_next(const iterator_base* it) const { m_next = it; } +inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; } -inline void iterator_base::register_self() { +inline void debug_iterator_base::register_self() { if (m_registry != 0) m_registry->register_iterator(this); } -inline void iterator_base::unregister_self() { +inline void debug_iterator_base::unregister_self() { if (m_registry != 0) m_registry->unregister_iterator(this); } -#else // #if BOOST_CB_ENABLE_DEBUG - -class iterator_registry { -#if BOOST_WORKAROUND(__BORLANDC__, < 0x6000) - char dummy_; // BCB: by default empty structure has 8 bytes -#endif -}; - -class iterator_base { -#if BOOST_WORKAROUND(__BORLANDC__, < 0x6000) - char dummy_; // BCB: by default empty structure has 8 bytes -#endif - -public: - iterator_base() {} - iterator_base(const iterator_registry*) {} -}; - #endif // #if BOOST_CB_ENABLE_DEBUG } // namespace cb_details Index: details.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/details.hpp,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- details.hpp 26 Feb 2007 22:37:09 -0000 1.23 +++ details.hpp 6 Mar 2007 00:03:46 -0000 1.24 @@ -191,8 +191,10 @@ typename Traits::value_type, typename Traits::difference_type, typename Traits::pointer, - typename Traits::reference>, - public iterator_base + typename Traits::reference> +#if BOOST_CB_ENABLE_DEBUG + , public debug_iterator_base +#endif // #if BOOST_CB_ENABLE_DEBUG { private: // Helper types @@ -226,6 +228,9 @@ //! Difference type. typedef typename base_iterator::difference_type difference_type; +#if !defined(BOOST_CB_TEST) +private: +#endif // #if !defined(BOOST_CB_TEST) // Member variables //! The circular buffer where the iterator points to. @@ -234,6 +239,7 @@ //! An internal iterator. pointer m_it; +public: // Construction & assignment // Default copy constructor. @@ -241,20 +247,32 @@ //! Default constructor. iterator() : m_buff(0), m_it(0) {} +#if BOOST_CB_ENABLE_DEBUG + //! Copy constructor (used for converting from a non-const to a const iterator). - iterator(const nonconst_self& it) : iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {} + iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {} //! Internal constructor. /*! \note This constructor is not intended to be used directly by the user. */ - iterator(const Buff* cb, const pointer p) : iterator_base(cb), m_buff(cb), m_it(p) {} + iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {} + +#else + + iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {} + + iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {} + +#endif // #if BOOST_CB_ENABLE_DEBUG //! Assign operator. iterator& operator = (const iterator& it) { if (this == &it) return *this; - iterator_base::operator =(it); +#if BOOST_CB_ENABLE_DEBUG + debug_iterator_base::operator =(it); +#endif // #if BOOST_CB_ENABLE_DEBUG m_buff = it.m_buff; m_it = it.m_it; return *this; |