Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58681 - in branches/release: boost/circular_buffer libs/circular_buffer/doc libs/circular_buffer/test
From: jano_gaspar_at_[hidden]
Date: 2010-01-04 10:54:38


Author: jano_gaspar
Date: 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
New Revision: 58681
URL: http://svn.boost.org/trac/boost/changeset/58681

Log:
circular_buffer: constant complexity of clear method and destructor; added erase_begin and erase_end methods
Added:
   branches/release/libs/circular_buffer/test/constant_erase_test.cpp (contents, props changed)
Text files modified:
   branches/release/boost/circular_buffer/base.hpp | 138 +++++++++++++++++++--
   branches/release/boost/circular_buffer/space_optimized.hpp | 26 ++-
   branches/release/libs/circular_buffer/doc/circular_buffer.html | 256 +++++++++++++++++++++++++++++++++++++++
   branches/release/libs/circular_buffer/doc/space_optimized.xslt | 4
   branches/release/libs/circular_buffer/test/Jamfile.v2 | 1
   5 files changed, 393 insertions(+), 32 deletions(-)

Modified: branches/release/boost/circular_buffer/base.hpp
==============================================================================
--- branches/release/boost/circular_buffer/base.hpp (original)
+++ branches/release/boost/circular_buffer/base.hpp 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -20,6 +20,7 @@
 #include <boost/iterator/iterator_traits.hpp>
 #include <boost/type_traits/is_stateless.hpp>
 #include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_scalar.hpp>
 #include <algorithm>
 #include <utility>
 #include <deque>
@@ -393,7 +394,7 @@
              Does not invalidate any iterators.
         \par Complexity
              Constant (in the size of the <code>circular_buffer</code>).
- \sa <code>operator[]</code>
+ \sa <code>\link operator[](size_type) operator[] \endlink</code>
     */
     reference at(size_type index) {
         check_position(index);
@@ -1165,7 +1166,7 @@
              Invalidates all iterators pointing to the <code>circular_buffer</code> (including iterators equal to
              <code>end()</code>).
         \par Complexity
- Linear (in the size of the <code>circular_buffer</code>).
+ Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
         \sa <code>clear()</code>
     */
     ~circular_buffer() {
@@ -1231,7 +1232,8 @@
              <code>end()</code>).
         \par Complexity
              Linear (in the <code>n</code>).
- \sa <code>operator=</code>, <code>\link assign(capacity_type, size_type, param_value_type)
+ \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
+ <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(InputIterator, InputIterator)</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
@@ -1260,8 +1262,9 @@
              <code>end()</code>).
         \par Complexity
              Linear (in the <code>n</code>).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>, <code>assign(InputIterator, InputIterator)</code>,
+ \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
+ <code>assign(InputIterator, InputIterator)</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
     */
     void assign(capacity_type buffer_capacity, size_type n, param_value_type item) {
@@ -1291,8 +1294,8 @@
              <code>end()</code>).
         \par Complexity
              Linear (in the <code>std::distance(first, last)</code>).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>,
+ \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
             <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
@@ -1330,8 +1333,8 @@
              Linear (in <code>std::distance(first, last)</code>; in
              <code>min[capacity, std::distance(first, last)]</code> if the <code>InputIterator</code> is a
              <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>,
+ \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
             <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(InputIterator, InputIterator)</code>
@@ -1805,7 +1808,8 @@
         \par Complexity
              Linear (in <code>std::distance(pos, end())</code>).
         \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
- <code>rerase(iterator, iterator)</code>, <code>clear()</code>
+ <code>rerase(iterator, iterator)</code>, <code>erase_begin(size_type)</code>,
+ <code>erase_end(size_type)</code>, <code>clear()</code>
     */
     iterator erase(iterator pos) {
         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
@@ -1842,7 +1846,7 @@
         \par Complexity
              Linear (in <code>std::distance(first, end())</code>).
         \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
- <code>clear()</code>
+ <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>, <code>clear()</code>
     */
     iterator erase(iterator first, iterator last) {
         BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator
@@ -1881,7 +1885,8 @@
               <code>erase(iterator)</code> if the iterator <code>pos</code> is close to the beginning of the
               <code>circular_buffer</code>. (See the <i>Complexity</i>.)
         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
- <code>rerase(iterator, iterator)</code>, <code>clear()</code>
+ <code>rerase(iterator, iterator)</code>, <code>erase_begin(size_type)</code>,
+ <code>erase_end(size_type)</code>, <code>clear()</code>
     */
     iterator rerase(iterator pos) {
         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
@@ -1921,7 +1926,7 @@
               <code>erase(iterator, iterator)</code> if <code>std::distance(begin(), first)</code> is lower that
               <code>std::distance(last, end())</code>.
         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
- <code>clear()</code>
+ <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>, <code>clear()</code>
     */
     iterator rerase(iterator first, iterator last) {
         BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator
@@ -1947,6 +1952,70 @@
         return iterator(this, last.m_it);
     }
 
+ //! Remove first <code>n</code> elements (with constant complexity for scalar types).
+ /*!
+ \pre <code>n \<= size()</code>
+ \post The <code>n</code> elements at the beginning of the <code>circular_buffer</code> will be removed.
+ \param n The number of elements to be removed.
+ \throws Whatever <code>T::operator = (const T&)</code> throws. (Does not throw anything in case of scalars.)
+ \par Exception Safety
+ Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw in
+ case of scalars.)
+ \par Iterator Invalidation
+ Invalidates iterators pointing to the first <code>n</code> erased elements.
+ \par Complexity
+ Constant (in <code>n</code>) for scalar types; linear for other types.
+ \note This method has been specially designed for types which do not require an explicit destructruction (e.g.
+ integer, float or a pointer). For these scalar types a call to a destructor is not required which makes
+ it possible to implement the "erase from beginning" operation with a constant complexity. For non-sacalar
+ types the complexity is linear (hence the explicit destruction is needed) and the implementation is
+ actually equivalent to
+ <code>\link circular_buffer::rerase(iterator, iterator) rerase(begin(), begin() + n)\endlink</code>.
+ \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
+ <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
+ <code>erase_end(size_type)</code>, <code>clear()</code>
+ */
+ void erase_begin(size_type n) {
+ BOOST_CB_ASSERT(n <= size()); // check for n greater than size
+#if BOOST_CB_ENABLE_DEBUG
+ erase_begin(n, false_type());
+#else
+ erase_begin(n, is_scalar<value_type>());
+#endif
+ }
+
+ //! Remove last <code>n</code> elements (with constant complexity for scalar types).
+ /*!
+ \pre <code>n \<= size()</code>
+ \post The <code>n</code> elements at the end of the <code>circular_buffer</code> will be removed.
+ \param n The number of elements to be removed.
+ \throws Whatever <code>T::operator = (const T&)</code> throws. (Does not throw anything in case of scalars.)
+ \par Exception Safety
+ Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw in
+ case of scalars.)
+ \par Iterator Invalidation
+ Invalidates iterators pointing to the last <code>n</code> erased elements.
+ \par Complexity
+ Constant (in <code>n</code>) for scalar types; linear for other types.
+ \note This method has been specially designed for types which do not require an explicit destructruction (e.g.
+ integer, float or a pointer). For these scalar types a call to a destructor is not required which makes
+ it possible to implement the "erase from end" operation with a constant complexity. For non-sacalar
+ types the complexity is linear (hence the explicit destruction is needed) and the implementation is
+ actually equivalent to
+ <code>\link circular_buffer::erase(iterator, iterator) erase(end() - n, end())\endlink</code>.
+ \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
+ <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
+ <code>erase_begin(size_type)</code>, <code>clear()</code>
+ */
+ void erase_end(size_type n) {
+ BOOST_CB_ASSERT(n <= size()); // check for n greater than size
+#if BOOST_CB_ENABLE_DEBUG
+ erase_end(n, false_type());
+#else
+ erase_end(n, is_scalar<value_type>());
+#endif
+ }
+
     //! Remove all stored elements from the <code>circular_buffer</code>.
     /*!
         \post <code>size() == 0</code>
@@ -1957,9 +2026,10 @@
              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
              <code>end()</code>).
         \par Complexity
- Linear (in the size of the <code>circular_buffer</code>).
+ Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
         \sa <code>~circular_buffer()</code>, <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
- <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>
+ <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
+ <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>
     */
     void clear() {
         destroy_content();
@@ -2066,6 +2136,20 @@
 
     //! Destroy the whole content of the circular buffer.
     void destroy_content() {
+#if BOOST_CB_ENABLE_DEBUG
+ destroy_content(false_type());
+#else
+ destroy_content(is_scalar<value_type>());
+#endif
+ }
+
+ //! Specialized destroy_content method.
+ void destroy_content(const true_type&) {
+ m_first = add(m_first, size());
+ }
+
+ //! Specialized destroy_content method.
+ void destroy_content(const false_type&) {
         for (size_type ii = 0; ii < size(); ++ii, increment(m_first))
             destroy_item(m_first);
     }
@@ -2564,6 +2648,30 @@
         m_last = sub(m_last, n - construct);
         m_size += construct;
     }
+
+ //! Specialized erase_begin method.
+ void erase_begin(size_type n, const true_type&) {
+ m_first = add(m_first, n);
+ m_size -= n;
+ }
+
+ //! Specialized erase_begin method.
+ void erase_begin(size_type n, const false_type&) {
+ iterator b = begin();
+ rerase(b, b + n);
+ }
+
+ //! Specialized erase_end method.
+ void erase_end(size_type n, const true_type&) {
+ m_last = sub(m_last, n);
+ m_size -= n;
+ }
+
+ //! Specialized erase_end method.
+ void erase_end(size_type n, const false_type&) {
+ iterator e = end();
+ erase(e - n, e);
+ }
 };
 
 // Non-member functions

Modified: branches/release/boost/circular_buffer/space_optimized.hpp
==============================================================================
--- branches/release/boost/circular_buffer/space_optimized.hpp (original)
+++ branches/release/boost/circular_buffer/space_optimized.hpp 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -189,9 +189,9 @@
         \par Complexity
              Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
         \note To explicitly clear the extra allocated memory use the <b>shrink-to-fit</b> technique:<br><br>
- <code>boost::%circular_buffer_space_optimized\<int\> cb(1000);<br>
+ <code>%boost::%circular_buffer_space_optimized\<int\> cb(1000);<br>
               ...<br>
- boost::%circular_buffer_space_optimized\<int\>(cb).swap(cb);</code><br><br>
+ %boost::%circular_buffer_space_optimized\<int\>(cb).swap(cb);</code><br><br>
               For more information about the shrink-to-fit technique in STL see
               <a href="http://www.gotw.ca/gotw/054.htm">http://www.gotw.ca/gotw/054.htm>.
         \sa <code>rset_capacity(const capacity_type&)</code>,
@@ -513,6 +513,12 @@
     */
     ~circular_buffer_space_optimized();
 
+ //! no-comment
+ void erase_begin(size_type n);
+
+ //! no-comment
+ void erase_end(size_type n);
+
 #endif // #if defined(BOOST_CB_NEVER_DEFINED)
 
     //! The assign operator.
@@ -565,7 +571,8 @@
              equal to <code>end()</code>).
         \par Complexity
              Linear (in the <code>n</code>).
- \sa <code>operator=</code>, <code>\link assign(capacity_type, size_type, param_value_type)
+ \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
+ <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(InputIterator, InputIterator)</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
@@ -597,8 +604,9 @@
              equal to <code>end()</code>).
         \par Complexity
              Linear (in the <code>n</code>).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>, <code>assign(InputIterator, InputIterator)</code>,
+ \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
+ <code>assign(InputIterator, InputIterator)</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
     */
     void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) {
@@ -630,8 +638,8 @@
              equal to <code>end()</code>).
         \par Complexity
              Linear (in the <code>std::distance(first, last)</code>).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>,
+ \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
             <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(capacity_type, InputIterator, InputIterator)</code>
@@ -672,8 +680,8 @@
              Linear (in <code>std::distance(first, last)</code>; in
              <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
              is a
RandomAccessIterator).
- \sa <code>operator=</code>, <code>\link assign(size_type, param_value_type)
- assign(size_type, const_reference)\endlink</code>,
+ \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
+ <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
             <code>\link assign(capacity_type, size_type, param_value_type)
             assign(capacity_type, size_type, const_reference)\endlink</code>,
             <code>assign(InputIterator, InputIterator)</code>

Modified: branches/release/libs/circular_buffer/doc/circular_buffer.html
==============================================================================
--- branches/release/libs/circular_buffer/doc/circular_buffer.html (original)
+++ branches/release/libs/circular_buffer/doc/circular_buffer.html 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -338,6 +338,8 @@
    iterator rerase(iterator pos);
    iterator <a href=
 "#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase</a>(iterator first, iterator last);
+ void erase_begin(size_type n);
+ void erase_end(size_type n);
    void clear();
 };
 
@@ -1607,7 +1609,7 @@
                 <b>Complexity:</b>
               </dt>
               <dd>
- Linear (in the size of the <code>circular_buffer</code>).
+ Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
               </dd>
             </dl>
             <dl>
@@ -6110,7 +6112,10 @@
                 "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
                 <code><a href="#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
                 iterator)</a></code>, <code><a href=
- "#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>,
+ <code>clear()</code>
               </dd>
             </dl>
           </td>
@@ -6222,7 +6227,10 @@
                 "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
                 <code><a href="#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
                 iterator)</a></code>, <code><a href=
- "#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>,
+ <code>clear()</code>
               </dd>
             </dl>
           </td>
@@ -6335,7 +6343,10 @@
                 iterator)</a></code>, <code><a href=
                 "#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
                 iterator)</a></code>, <code><a href=
- "#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>,
+ <code>clear()</code>
               </dd>
             </dl>
           </td>
@@ -6460,6 +6471,219 @@
                 <code><a href="#classboost_1_1circular__buffer_1a96415389509a18bd7d7b5d8e4dda9bd">erase(iterator,
                 iterator)</a></code>, <code><a href=
                 "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>,
+ <code>clear()</code>
+ </dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a id="classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd" name=
+ "classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd"></a><code><b>void erase_begin(<a href=
+ "#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n);</b></code><br>
+ <br>
+ Remove first <code>n</code> elements (with constant complexity for scalar types).
+ <dl>
+ <dt>
+ <b>Precondition:</b>
+ </dt>
+ <dd>
+ <code>n &lt;= <a href=
+ "#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a></code>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Effect:</b>
+ </dt>
+ <dd>
+ The <code>n</code> elements at the beginning of the <code>circular_buffer</code> will be removed.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Parameter(s):</b>
+ </dt>
+ <dd>
+ <dl compact>
+ <dt>
+ <code>n</code>
+ </dt>
+ <dd>
+ The number of elements to be removed.
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Throws:</b>
+ </dt>
+ <dd>
+ Whatever <code>T::operator = (const T&amp;)</code> throws. (Does not throw anything in case of
+ scalars.)
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Exception Safety:</b>
+ </dt>
+ <dd>
+ Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw
+ in case of scalars.)
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Iterator Invalidation:</b>
+ </dt>
+ <dd>
+ Invalidates iterators pointing to the first <code>n</code> erased elements.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Complexity:</b>
+ </dt>
+ <dd>
+ Constant (in <code>n</code>) for scalar types; linear for other types.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Note:</b>
+ </dt>
+ <dd>
+ This method has been specially designed for types which do not require an explicit destructruction
+ (e.g. integer, float or a pointer). For these scalar types a call to a destructor is not required which
+ makes it possible to implement the "erase from beginning" operation with a constant complexity. For
+ non-sacalar types the complexity is linear (hence the explicit destruction is needed) and the
+ implementation is actually equivalent to <code><a href=
+ "#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(begin(), begin() +
+ n)</a></code>.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>See Also:</b>
+ </dt>
+ <dd>
+ <code><a href=
+ "#classboost_1_1circular__buffer_197155de712db1759e1698455b49a0be3">erase(iterator)</a></code>,
+ <code><a href="#classboost_1_1circular__buffer_1a96415389509a18bd7d7b5d8e4dda9bd">erase(iterator,
+ iterator)</a></code>, <code><a href=
+ "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
+ <code><a href="#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
+ iterator)</a></code>, <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>,
+ <code>clear()</code>
+ </dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a id="classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7" name=
+ "classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7"></a><code><b>void erase_end(<a href=
+ "#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n);</b></code><br>
+ <br>
+ Remove last <code>n</code> elements (with constant complexity for scalar types).
+ <dl>
+ <dt>
+ <b>Precondition:</b>
+ </dt>
+ <dd>
+ <code>n &lt;= <a href=
+ "#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a></code>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Effect:</b>
+ </dt>
+ <dd>
+ The <code>n</code> elements at the end of the <code>circular_buffer</code> will be removed.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Parameter(s):</b>
+ </dt>
+ <dd>
+ <dl compact>
+ <dt>
+ <code>n</code>
+ </dt>
+ <dd>
+ The number of elements to be removed.
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Throws:</b>
+ </dt>
+ <dd>
+ Whatever <code>T::operator = (const T&amp;)</code> throws. (Does not throw anything in case of
+ scalars.)
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Exception Safety:</b>
+ </dt>
+ <dd>
+ Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw
+ in case of scalars.)
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Iterator Invalidation:</b>
+ </dt>
+ <dd>
+ Invalidates iterators pointing to the last <code>n</code> erased elements.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Complexity:</b>
+ </dt>
+ <dd>
+ Constant (in <code>n</code>) for scalar types; linear for other types.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>Note:</b>
+ </dt>
+ <dd>
+ This method has been specially designed for types which do not require an explicit destructruction
+ (e.g. integer, float or a pointer). For these scalar types a call to a destructor is not required which
+ makes it possible to implement the "erase from end" operation with a constant complexity. For
+ non-sacalar types the complexity is linear (hence the explicit destruction is needed) and the
+ implementation is actually equivalent to <code><a href=
+ "#classboost_1_1circular__buffer_1a96415389509a18bd7d7b5d8e4dda9bd">erase(end() - n, end())</a></code>.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b>See Also:</b>
+ </dt>
+ <dd>
+ <code><a href=
+ "#classboost_1_1circular__buffer_197155de712db1759e1698455b49a0be3">erase(iterator)</a></code>,
+ <code><a href="#classboost_1_1circular__buffer_1a96415389509a18bd7d7b5d8e4dda9bd">erase(iterator,
+ iterator)</a></code>, <code><a href=
+ "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
+ <code><a href="#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
+ iterator)</a></code>, <code><a href=
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
                 <code>clear()</code>
               </dd>
             </dl>
@@ -6511,7 +6735,7 @@
                 <b>Complexity:</b>
               </dt>
               <dd>
- Linear (in the size of the <code>circular_buffer</code>).
+ Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
               </dd>
             </dl>
             <dl>
@@ -6527,7 +6751,10 @@
                 iterator)</a></code>, <code><a href=
                 "#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase(iterator)</a></code>,
                 <code><a href="#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase(iterator,
- iterator)</a></code>
+ iterator)</a></code>, <code><a href=
+ "#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin(size_type)</a></code>,
+ <code><a href=
+ "#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end(size_type)</a></code>
               </dd>
             </dl>
           </td>
@@ -7125,6 +7352,23 @@
     <dl>
       <dd>
         <h3>
+ Boost 1.42
+ </h3>
+ </dd>
+ <dd>
+ <ul>
+ <li>Added methods <code>erase_begin(size_type)</code> and <code>erase_end(size_type)</code> with constant
+ complexity for such types of stored elements which do not need an explicit destruction e.g. <code>int</code>
+ or <code>double</code>.
+ </li>
+ <li>Similarly changed implementation of the <code>clear()</code> method and the destructor so their
+ complexity is now constant for such types of stored elements which do not require an explicit destruction
+ (the complexity for other types remains linear).
+ </li>
+ </ul>
+ </dd>
+ <dd>
+ <h3>
           Boost 1.37
         </h3>
       </dd>

Modified: branches/release/libs/circular_buffer/doc/space_optimized.xslt
==============================================================================
--- branches/release/libs/circular_buffer/doc/space_optimized.xslt (original)
+++ branches/release/libs/circular_buffer/doc/space_optimized.xslt 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -68,7 +68,7 @@
         </xsl:apply-templates>
       </xsl:if>
     </xsl:for-each>
- <xsl:for-each select="$current[string-length(normalize-space(briefdescription)) &gt; 0]">
+ <xsl:for-each select="$current[string-length(normalize-space(briefdescription)) &gt; 0 and normalize-space(briefdescription) != 'no-comment']">
       <xsl:apply-templates select="." mode="synopsis"/>
     </xsl:for-each>
   </xsl:template>
@@ -96,7 +96,7 @@
   </xsl:template>
 
   <xsl:template name="member-functions-details">
- <xsl:for-each select="sectiondef[@kind='public-func']/memberdef[type != '' and string-length(normalize-space(briefdescription)) &gt; 0]">
+ <xsl:for-each select="sectiondef[@kind='public-func']/memberdef[type != '' and string-length(normalize-space(briefdescription)) &gt; 0 and normalize-space(briefdescription) != 'no-comment']">
       <xsl:apply-templates select="." mode="description"/>
     </xsl:for-each>
   </xsl:template>

Modified: branches/release/libs/circular_buffer/test/Jamfile.v2
==============================================================================
--- branches/release/libs/circular_buffer/test/Jamfile.v2 (original)
+++ branches/release/libs/circular_buffer/test/Jamfile.v2 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -25,5 +25,6 @@
   : [ run base_test.cpp : <threading>single : ]
     [ run space_optimized_test.cpp : <threading>single : ]
     [ run soft_iterator_invalidation.cpp : <threading>single : ]
+ [ run constant_erase_test.cpp : <threading>single : ]
     [ compile bounded_buffer_comparison.cpp : <threading>multi : ]
   ;

Added: branches/release/libs/circular_buffer/test/constant_erase_test.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/circular_buffer/test/constant_erase_test.cpp 2010-01-04 10:54:37 EST (Mon, 04 Jan 2010)
@@ -0,0 +1,187 @@
+// Special tests for erase_begin, erase_end and clear methods.
+
+// Copyright (c) 2009 Jan Gaspar
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CB_DISABLE_DEBUG
+
+#include "test.hpp"
+
+int MyInteger::ms_exception_trigger = 0;
+int InstanceCounter::ms_count = 0;
+
+void erase_begin_test() {
+
+ circular_buffer<int> cb1(5);
+ cb1.push_back(1);
+ cb1.push_back(2);
+ cb1.push_back(3);
+ cb1.push_back(4);
+ cb1.push_back(5);
+ cb1.push_back(6);
+
+ circular_buffer<int>::pointer p = &cb1[0];
+
+ cb1.erase_begin(2);
+
+ BOOST_CHECK(cb1.size() == 3);
+ BOOST_CHECK(cb1[0] == 4);
+ BOOST_CHECK(cb1[1] == 5);
+ BOOST_CHECK(cb1[2] == 6);
+
+ cb1.erase_begin(3);
+ BOOST_CHECK(cb1.empty());
+ BOOST_CHECK(*p == 2);
+ BOOST_CHECK(*(p + 1) == 3);
+ BOOST_CHECK(*(p + 2) == 4);
+
+ cb1.push_back(10);
+ cb1.push_back(11);
+ cb1.push_back(12);
+
+ BOOST_CHECK(cb1.size() == 3);
+ BOOST_CHECK(cb1[0] == 10);
+ BOOST_CHECK(cb1[1] == 11);
+ BOOST_CHECK(cb1[2] == 12);
+
+ circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+ BOOST_CHECK(cb2.size() == 5);
+ BOOST_CHECK(InstanceCounter::count() == 5);
+
+ cb2.erase_begin(2);
+
+ BOOST_CHECK(cb2.size() == 3);
+ BOOST_CHECK(InstanceCounter::count() == 3);
+
+ circular_buffer<MyInteger> cb3(5);
+ cb3.push_back(1);
+ cb3.push_back(2);
+ cb3.push_back(3);
+ cb3.push_back(4);
+ cb3.push_back(5);
+ cb3.push_back(6);
+ cb3.erase_begin(2);
+
+ BOOST_CHECK(cb3.size() == 3);
+ BOOST_CHECK(cb3[0] == 4);
+ BOOST_CHECK(cb3[1] == 5);
+ BOOST_CHECK(cb3[2] == 6);
+}
+
+void erase_end_test() {
+
+ circular_buffer<int> cb1(5);
+ cb1.push_back(1);
+ cb1.push_back(2);
+ cb1.push_back(3);
+ cb1.push_back(4);
+ cb1.push_back(5);
+ cb1.push_back(6);
+
+ circular_buffer<int>::pointer p = &cb1[3];
+
+ cb1.erase_end(2);
+
+ BOOST_CHECK(cb1.size() == 3);
+ BOOST_CHECK(cb1[0] == 2);
+ BOOST_CHECK(cb1[1] == 3);
+ BOOST_CHECK(cb1[2] ==4);
+
+ cb1.erase_end(3);
+ BOOST_CHECK(cb1.empty());
+ BOOST_CHECK(*p == 5);
+ BOOST_CHECK(*(p - 1) == 4);
+ BOOST_CHECK(*(p - 2) == 3);
+
+ cb1.push_back(10);
+ cb1.push_back(11);
+ cb1.push_back(12);
+
+ BOOST_CHECK(cb1.size() == 3);
+ BOOST_CHECK(cb1[0] == 10);
+ BOOST_CHECK(cb1[1] == 11);
+ BOOST_CHECK(cb1[2] == 12);
+
+ circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+ BOOST_CHECK(cb2.size() == 5);
+ BOOST_CHECK(InstanceCounter::count() == 5);
+
+ cb2.erase_end(2);
+
+ BOOST_CHECK(cb2.size() == 3);
+ BOOST_CHECK(InstanceCounter::count() == 3);
+
+ circular_buffer<MyInteger> cb3(5);
+ cb3.push_back(1);
+ cb3.push_back(2);
+ cb3.push_back(3);
+ cb3.push_back(4);
+ cb3.push_back(5);
+ cb3.push_back(6);
+ cb3.erase_end(2);
+
+ BOOST_CHECK(cb3.size() == 3);
+ BOOST_CHECK(cb3[0] == 2);
+ BOOST_CHECK(cb3[1] == 3);
+ BOOST_CHECK(cb3[2] == 4);
+}
+
+void clear_test() {
+
+ circular_buffer<int> cb1(5);
+ cb1.push_back(1);
+ cb1.push_back(2);
+ cb1.push_back(3);
+ cb1.push_back(4);
+ cb1.push_back(5);
+ cb1.push_back(6);
+
+ circular_buffer<int>::pointer p = &cb1[0];
+
+ cb1.clear();
+
+ BOOST_CHECK(cb1.empty());
+ BOOST_CHECK(*p == 2);
+ BOOST_CHECK(*(p + 1) == 3);
+ BOOST_CHECK(*(p + 2) == 4);
+ BOOST_CHECK(*(p + 3) == 5);
+ BOOST_CHECK(*(p - 1) == 6);
+
+ circular_buffer<InstanceCounter> cb2(5, InstanceCounter());
+
+ BOOST_CHECK(cb2.size() == 5);
+ BOOST_CHECK(InstanceCounter::count() == 5);
+
+ cb2.clear();
+
+ BOOST_CHECK(cb2.empty());
+ BOOST_CHECK(InstanceCounter::count() == 0);
+
+ circular_buffer<MyInteger> cb3(5);
+ cb3.push_back(1);
+ cb3.push_back(2);
+ cb3.push_back(3);
+ cb3.push_back(4);
+ cb3.push_back(5);
+ cb3.push_back(6);
+ cb3.clear();
+
+ BOOST_CHECK(cb3.empty());
+}
+
+// test main
+test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) {
+
+ test_suite* tests = BOOST_TEST_SUITE("Unit tests for erase_begin/end and clear methods of the circular_buffer.");
+
+ tests->add(BOOST_TEST_CASE(&erase_begin_test));
+ tests->add(BOOST_TEST_CASE(&erase_end_test));
+ tests->add(BOOST_TEST_CASE(&clear_test));
+
+ return tests;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk