$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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 <= <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&)</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 <= <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&)</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)) > 0]">
+    <xsl:for-each select="$current[string-length(normalize-space(briefdescription)) > 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)) > 0]">
+    <xsl:for-each select="sectiondef[@kind='public-func']/memberdef[type != '' and string-length(normalize-space(briefdescription)) > 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;
+}