|
From: Jan G. <jan...@us...> - 2007-02-26 22:37:11
|
Update of /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv4706/boost/circular_buffer Modified Files: base.hpp debug.hpp details.hpp Log Message: Fixed and improved debug support. Index: base.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/base.hpp,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- base.hpp 19 Feb 2007 23:18:10 -0000 1.80 +++ base.hpp 26 Feb 2007 22:37:08 -0000 1.81 @@ -60,7 +60,7 @@ http://www.boost.org/libs/circular_buffer/doc/circular_buffer.html */ template <class T, class Alloc> -class circular_buffer : cb_details::iterator_registry { +class circular_buffer : public cb_details::iterator_registry { // Requirements BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); @@ -378,7 +378,7 @@ //! Get the element at the <code>index</code> position. /*! \param index The position of the element. - \return A const reference to the element at the <code>index</code> position. + \return A reference to the element at the <code>index</code> position. \throws <code>std::out_of_range</code> when the <code>index</code> is invalid (when <code>index >= size()</code>). \par Complexity @@ -653,6 +653,9 @@ destroy_item(src); m_first = m_buff; m_last = add(m_buff, size()); +#if BOOST_CB_ENABLE_DEBUG + invalidate_all_iterators(); +#endif return m_buff; } @@ -760,7 +763,8 @@ \par Exception Safety Strong. \par Iterator Invalidation - Invalidates all iterators pointing to the <code>circular_buffer</code>. + Invalidates all iterators pointing to the <code>circular_buffer</code> if the new capacity is different + from the original. \sa <code>rset_capacity()</code>, <code>resize()</code> */ void set_capacity(capacity_type new_capacity) { @@ -768,7 +772,9 @@ return; pointer buff = allocate(new_capacity); BOOST_TRY { - reset(buff, cb_details::uninitialized_copy(begin(), begin() + std::min(new_capacity, size()), buff, m_alloc), new_capacity); + reset(buff, + cb_details::uninitialized_copy(begin(), begin() + std::min(new_capacity, size()), buff, m_alloc), + new_capacity); } BOOST_CATCH(...) { deallocate(buff, new_capacity); BOOST_RETHROW @@ -796,7 +802,8 @@ \par Exception Safety Basic. \par Iterator Invalidation - Invalidates all iterators pointing to the <code>circular_buffer</code>. + Invalidates all iterators pointing to the <code>circular_buffer</code> if the new size is different from + the original. \sa <code>rresize()</code>, <code>set_capacity()</code> */ void resize(size_type new_size, param_value_type item = value_type()) { @@ -823,7 +830,8 @@ \par Exception Safety Strong. \par Iterator Invalidation - Invalidates all iterators pointing to the <code>circular_buffer</code>. + Invalidates all iterators pointing to the <code>circular_buffer</code> if the new capacity is different + from the original. \sa <code>set_capacity()</code>, <code>rresize()</code> */ void rset_capacity(capacity_type new_capacity) { @@ -831,7 +839,8 @@ return; pointer buff = allocate(new_capacity); BOOST_TRY { - reset(buff, cb_details::uninitialized_copy(end() - std::min(new_capacity, size()), end(), buff, m_alloc), new_capacity); + reset(buff, cb_details::uninitialized_copy(end() - std::min(new_capacity, size()), end(), buff, m_alloc), + new_capacity); } BOOST_CATCH(...) { deallocate(buff, new_capacity); BOOST_RETHROW @@ -851,14 +860,16 @@ \param new_size The new size. \param item The element the <code>circular_buffer</code> will be filled with in order to gain the requested size. (See the postcondition.) - \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is used). + \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is + used). \throws Whatever <code>T::T(const T&)</code> throws. \par Complexity Linear (in the new size of the <code>circular_buffer</code>). \par Exception Safety Basic. \par Iterator Invalidation - Invalidates all iterators pointing to the <code>circular_buffer</code>. + Invalidates all iterators pointing to the <code>circular_buffer</code> if the new size is different from + the original. \sa <code>rresize()</code>, <code>set_capacity()</code> */ void rresize(size_type new_size, param_value_type item = value_type()) { @@ -884,8 +895,7 @@ \note This constructor has been defined only due to compatibility with the STL container definition. Avoid using it because it allocates very large amount of memory. */ - explicit circular_buffer( - const allocator_type& alloc = allocator_type()) + explicit circular_buffer(const allocator_type& alloc = allocator_type()) : m_size(0), m_alloc(alloc) { initialize(max_size()); } @@ -900,9 +910,7 @@ \par Complexity Constant. */ - explicit circular_buffer( - capacity_type capacity, - const allocator_type& alloc = allocator_type()) + explicit circular_buffer(capacity_type capacity, const allocator_type& alloc = allocator_type()) : m_size(0), m_alloc(alloc) { initialize(capacity); } @@ -920,10 +928,7 @@ \par Complexity Linear (in the <code>n</code>). */ - circular_buffer( - size_type n, - param_value_type item, - const allocator_type& alloc = allocator_type()) + circular_buffer(size_type n, param_value_type item, const allocator_type& alloc = allocator_type()) : m_size(n), m_alloc(alloc) { initialize(n, item); } @@ -943,10 +948,7 @@ \par Complexity Linear (in the <code>n</code>). */ - circular_buffer( - capacity_type capacity, - size_type n, - param_value_type item, + circular_buffer(capacity_type capacity, size_type n, param_value_type item, const allocator_type& alloc = allocator_type()) : m_size(n), m_alloc(alloc) { BOOST_CB_ASSERT(capacity >= size()); // check for capacity lower than size @@ -980,18 +982,13 @@ /*! \cond */ template <class InputIterator> - circular_buffer( - InputIterator first, - InputIterator last) + circular_buffer(InputIterator first, InputIterator last) : m_alloc(allocator_type()) { initialize(first, last, is_integral<InputIterator>()); } template <class InputIterator> - circular_buffer( - capacity_type capacity, - InputIterator first, - InputIterator last) + circular_buffer(capacity_type capacity, InputIterator first, InputIterator last) : m_alloc(allocator_type()) { initialize(capacity, first, last, is_integral<InputIterator>()); } @@ -1017,10 +1014,7 @@ Linear (in the <code>std::distance(first, last)</code>). */ template <class InputIterator> - circular_buffer( - InputIterator first, - InputIterator last, - const allocator_type& alloc = allocator_type()) + circular_buffer(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : m_alloc(alloc) { initialize(first, last, is_integral<InputIterator>()); } @@ -1047,10 +1041,7 @@ Linear (in the <code>capacity</code>/<code>std::distance(first, last)</code>). */ template <class InputIterator> - circular_buffer( - capacity_type capacity, - InputIterator first, - InputIterator last, + circular_buffer(capacity_type capacity, InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : m_alloc(alloc) { initialize(capacity, first, last, is_integral<InputIterator>()); @@ -1140,8 +1131,8 @@ The capacity of the <code>circular_buffer</code> will be set to the specified value and the content of the <code>circular_buffer</code> will be removed and replaced with <code>n</code> copies of the <code>item</code>. \pre <code>capacity >= n</code> - \post <code>capacity() == capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... \&\& - (*this) [n - 1] == item </code> + \post <code>capacity() == capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this) [n - 1] == item </code> \param capacity The new capacity of the <code>circular_buffer</code>. \param n The number of elements the <code>circular_buffer</code> will be filled with. \param item The element the <code>circular_buffer</code> will be filled with. @@ -1396,7 +1387,7 @@ <code>rinsert(iterator, InputIterator, InputIterator)</code> */ iterator insert(iterator pos, param_value_type item = value_type()) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator if (full() && pos == begin()) return begin(); return insert_item(pos, item); @@ -1436,7 +1427,7 @@ <code>rinsert(iterator, InputIterator, InputIterator)</code> */ void insert(iterator pos, size_type n, param_value_type item) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator if (n == 0) return; size_type copy = capacity() - (end() - pos); @@ -1486,7 +1477,7 @@ */ template <class InputIterator> void insert(iterator pos, InputIterator first, InputIterator last) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator insert(pos, first, last, is_integral<InputIterator>()); } @@ -1515,7 +1506,7 @@ <code>insert(iterator, InputIterator, InputIterator)</code> */ iterator rinsert(iterator pos, param_value_type item = value_type()) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator if (full() && pos.m_it == 0) return end(); if (pos == begin()) { @@ -1592,7 +1583,7 @@ <code>insert(iterator, InputIterator, InputIterator)</code> */ void rinsert(iterator pos, size_type n, param_value_type item) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator rinsert_n(pos, n, cb_details::item_wrapper<const_pointer, param_value_type>(item)); } @@ -1634,7 +1625,7 @@ */ template <class InputIterator> void rinsert(iterator pos, InputIterator first, InputIterator last) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator rinsert(pos, first, last, is_integral<InputIterator>()); } @@ -1659,8 +1650,8 @@ <code>rerase(iterator, iterator)</code>, <code>clear()</code> */ iterator erase(iterator pos) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() pointer next = pos.m_it; increment(next); for (pointer p = pos.m_it; next != m_last; p = next, increment(next)) @@ -1678,7 +1669,8 @@ //! Erase the range <code>[first, last)</code>. /*! \pre Valid range <code>[first, last)</code>. - \post The elements from the range <code>[first, last)</code> are removed. + \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code> + nothing is removed.) \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such element exists. \throws Whatever <code>T::operator = (const T&)</code> throws. @@ -1693,10 +1685,9 @@ <code>clear()</code> */ iterator erase(iterator first, iterator last) { - BOOST_CB_ASSERT(first.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(last.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(first.m_buff == last.m_buff); // check for iterators of different containers - BOOST_CB_ASSERT(first <= last); // check for wrong range + BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(last.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(first <= last); // check for wrong range if (first == last) return first; pointer p = first.m_it; @@ -1728,8 +1719,8 @@ <code>rerase(iterator, iterator)</code>, <code>clear()</code> */ iterator rerase(iterator pos) { - BOOST_CB_ASSERT(pos.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() pointer prev = pos.m_it; pointer p = prev; for (decrement(prev); p != m_first; p = prev, decrement(prev)) @@ -1762,10 +1753,9 @@ <code>clear()</code> */ iterator rerase(iterator first, iterator last) { - BOOST_CB_ASSERT(first.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(last.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(first.m_buff == last.m_buff); // check for iterators of different containers - BOOST_CB_ASSERT(first <= last); // check for wrong range + BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(last.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(first <= last); // check for wrong range if (first == last) return first; pointer p = map_pointer(last.m_it); @@ -1906,6 +1896,9 @@ 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. @@ -1955,7 +1948,8 @@ //! Specialized initialize method. template <class InputIterator> void initialize(InputIterator first, InputIterator last, const std::input_iterator_tag&) { - BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors for containers + BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors + // for containers std::deque<value_type, allocator_type> tmp(first, last, m_alloc); size_type distance = tmp.size(); initialize(distance, tmp.begin(), tmp.end(), distance); @@ -2075,10 +2069,13 @@ //! Specialized assign method. template <class InputIterator> void assign(InputIterator first, InputIterator last, const std::input_iterator_tag&) { - BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors for containers + BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors + // for containers std::deque<value_type, allocator_type> tmp(first, last, m_alloc); size_type distance = tmp.size(); - assign_n(distance, distance, cb_details::assign_range<BOOST_DEDUCED_TYPENAME std::deque<value_type, allocator_type>::iterator, allocator_type>(tmp.begin(), tmp.end(), m_alloc)); + assign_n(distance, distance, + cb_details::assign_range<BOOST_DEDUCED_TYPENAME std::deque<value_type, allocator_type>::iterator, + allocator_type>(tmp.begin(), tmp.end(), m_alloc)); } //! Specialized assign method. @@ -2121,14 +2118,16 @@ //! Specialized assign method. template <class ForwardIterator> - void assign(capacity_type new_capacity, ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { + void assign(capacity_type new_capacity, ForwardIterator first, ForwardIterator last, + const std::forward_iterator_tag&) { BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range size_type distance = std::distance(first, last); if (distance > new_capacity) { std::advance(first, distance - capacity); distance = new_capacity; } - assign_n(new_capacity, distance, cb_details::assign_range<ForwardIterator, allocator_type>(first, last, m_alloc)); + assign_n(new_capacity, distance, + cb_details::assign_range<ForwardIterator, allocator_type>(first, last, m_alloc)); } //! Helper assign method. Index: debug.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/debug.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- debug.hpp 13 Feb 2006 01:01:17 -0000 1.9 +++ debug.hpp 26 Feb 2007 22:37:09 -0000 1.10 @@ -62,7 +62,7 @@ iterator_base& operator = (const iterator_base& rhs); //! Is the iterator valid? - bool is_valid() const; + bool is_valid(const iterator_registry* registry) const; //! Invalidate the iterator. /*! @@ -184,7 +184,7 @@ return *this; } -inline bool iterator_base::is_valid() const { return m_registry != 0; } +inline bool iterator_base::is_valid(const iterator_registry* registry) const { return m_registry == registry; } inline void iterator_base::invalidate() const { m_registry = 0; } Index: details.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/circular_buffer/details.hpp,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- details.hpp 19 Feb 2007 23:18:10 -0000 1.22 +++ details.hpp 26 Feb 2007 22:37:09 -0000 1.23 @@ -264,8 +264,8 @@ //! Dereferencing operator. reference operator * () const { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() return *m_it; } @@ -274,9 +274,8 @@ //! Difference operator. difference_type operator - (const iterator& it) const { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(it.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_buff == it.m_buff); // check for iterators of different containers + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator helper_pointer<Traits> lhs = create_helper_pointer(*this); helper_pointer<Traits> rhs = create_helper_pointer(it); if (less(rhs, lhs) && lhs.m_it <= rhs.m_it) @@ -288,8 +287,8 @@ //! Increment operator (prefix). iterator& operator ++ () { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() m_buff->increment(m_it); if (m_it == m_buff->m_last) m_it = 0; @@ -305,7 +304,7 @@ //! Decrement operator (prefix). iterator& operator -- () { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin() if (m_it == 0) m_it = m_buff->m_last; @@ -322,7 +321,7 @@ //! Iterator addition. iterator& operator += (difference_type n) { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator if (n > 0) { BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n m_it = m_buff->add(m_it, n); @@ -339,7 +338,7 @@ //! Iterator subtraction. iterator& operator -= (difference_type n) { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator if (n > 0) { BOOST_CB_ASSERT(m_buff->begin() - *this <= -n); // check for too large n m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n); @@ -360,27 +359,24 @@ //! Equality. template <class Traits0> bool operator == (const iterator<Buff, Traits0>& it) const { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(it.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_buff == it.m_buff); // check for iterators of different containers + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator return m_it == it.m_it; } //! Inequality. template <class Traits0> bool operator != (const iterator<Buff, Traits0>& it) const { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(it.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_buff == it.m_buff); // check for iterators of different containers + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator return m_it != it.m_it; } //! Less. template <class Traits0> bool operator < (const iterator<Buff, Traits0>& it) const { - BOOST_CB_ASSERT(is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(it.is_valid()); // check for uninitialized or invalidated iterator - BOOST_CB_ASSERT(m_buff == it.m_buff); // check for iterators of different containers + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator return less(create_helper_pointer(*this), create_helper_pointer(it)); } |