Compare commits

..

12 Commits

Author SHA1 Message Date
Beman Dawes
3916e22673 Release 1.45.0 beta 1
[SVN r66473]
2010-11-09 18:22:33 +00:00
Jan Gaspar
2bd298dec7 circular_buffer: applied patch to remove workaround for DEC C++ compiler - now all compilers will use this->invalidate_iterators_except
[SVN r61570]
2010-04-26 09:40:08 +00:00
Jan Gaspar
65810242ee circular_buffer: updated documentation
[SVN r60691]
2010-03-18 12:39:52 +00:00
Jan Gaspar
0282b8ee74 circular_buffer: constant complexity of clear method and destructor; added erase_begin and erase_end methods
[SVN r58681]
2010-01-04 15:54:37 +00:00
Troy D. Straszheim
cde2abac0c rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Jan Gaspar
f2247e1b9b circular_buffer: #3285
[SVN r55260]
2009-07-29 13:20:21 +00:00
Troy D. Straszheim
d532095822 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Jan Gaspar
5f566ba7bc circular_buffer: #2785, #3032
[SVN r53652]
2009-06-05 10:33:11 +00:00
Jeremiah Willcock
5aa54f6045 Fixed almost all tab and min/max issues found by inspect tool
[SVN r53142]
2009-05-20 19:41:20 +00:00
Douglas Gregor
8377fd145e Circular_buffer depends on Thread
[SVN r52817]
2009-05-07 04:42:14 +00:00
Troy D. Straszheim
92c290536e merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Jan Gaspar
8a115a066a circular_buffer: #2538 Warning suppression in circular buffer test jamfile
[SVN r50107]
2008-12-04 09:09:48 +00:00
9 changed files with 771 additions and 185 deletions

View File

@@ -65,6 +65,9 @@
<dt>
<a href="#debug">Debug Support</a>
</dt>
<dt>
<a href="#interprocess">Compatibility with Interprocess library</a>
</dt>
<dt>
<a href="#examples">More Examples</a>
</dt>
@@ -238,11 +241,11 @@ public:
explicit <a href=
"#classboost_1_1circular__buffer_1e53e744d2f94a2bcbfcdb219a9d93300">circular_buffer</a>(const allocator_type&amp; alloc = allocator_type());
explicit <a href=
"#classboost_1_1circular__buffer_1862a64cbc6a49376ecbb8321c3b44974">circular_buffer</a>(capacity_type capacity, const allocator_type&amp; alloc = allocator_type());
"#classboost_1_1circular__buffer_18f1606a26fead923c2cbe068a74e28b6">circular_buffer</a>(capacity_type buffer_capacity, const allocator_type&amp; alloc = allocator_type());
<a href=
"#classboost_1_1circular__buffer_1fdace8f110d5b7a17c02020757f06fe8">circular_buffer</a>(size_type n, const_reference item, const allocator_type&amp; alloc = allocator_type());
<a href=
"#classboost_1_1circular__buffer_10c7e9286d8270357d7e369b183124239">circular_buffer</a>(capacity_type capacity, size_type n, const_reference item, const allocator_type&amp; alloc = allocator_type());
"#classboost_1_1circular__buffer_104dc644486d835b56aa479ec48b52230">circular_buffer</a>(capacity_type buffer_capacity, size_type n, const_reference item, const allocator_type&amp; alloc = allocator_type());
<a href=
"#classboost_1_1circular__buffer_1e515d8a951eeb18b8cc930300e7e13bd">circular_buffer</a>(const circular_buffer&lt;T, Alloc&gt;&amp; cb);
template &lt;class InputIterator&gt;
@@ -250,7 +253,7 @@ public:
"#classboost_1_1circular__buffer_1744ec06b06a5a723386b645a29cb8ed2">circular_buffer</a>(InputIterator first, InputIterator last, const allocator_type&amp; alloc = allocator_type());
template &lt;class InputIterator&gt;
<a href=
"#classboost_1_1circular__buffer_1a64dcad327971194a706d52487151eb7">circular_buffer</a>(capacity_type capacity, InputIterator first, InputIterator last, const allocator_type&amp; alloc = allocator_type());
"#classboost_1_1circular__buffer_1a851f75f4a85b1a2b1a241904d21503f">circular_buffer</a>(capacity_type buffer_capacity, InputIterator first, InputIterator last, const allocator_type&amp; alloc = allocator_type());
<a href="#classboost_1_1circular__buffer_164250ffbbbdbc62b99e8301fc195b80c">~circular_buffer</a>();
allocator_type <a href=
@@ -303,13 +306,13 @@ public:
void <a href=
"#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign</a>(size_type n, const_reference item);
void <a href=
"#classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca">assign</a>(capacity_type capacity, size_type n, const_reference item);
"#classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a">assign</a>(capacity_type buffer_capacity, size_type n, const_reference item);
template &lt;class InputIterator&gt;
void <a href=
"#classboost_1_1circular__buffer_1253302d9bda5d7efbc4a6c311de3790c">assign</a>(InputIterator first, InputIterator last);
template &lt;class InputIterator&gt;
void <a href=
"#classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6">assign</a>(capacity_type capacity, InputIterator first, InputIterator last);
"#classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366">assign</a>(capacity_type buffer_capacity, InputIterator first, InputIterator last);
void <a href=
"#classboost_1_1circular__buffer_1270ab7074c365663a6f18808024fd88b">swap</a>(circular_buffer&lt;T, Alloc&gt;&amp; cb);
void <a href=
@@ -338,6 +341,8 @@ public:
iterator <a href="#classboost_1_1circular__buffer_1b6d4ae77d7445f844e30e78592f1e06f">rerase</a>(iterator pos);
iterator <a href=
"#classboost_1_1circular__buffer_1b0f98ae303584ded5397f067bbfc911f">rerase</a>(iterator first, iterator last);
void <a href="#classboost_1_1circular__buffer_1b25d379cf66ace025036a47ddb344abd">erase_begin</a>(size_type n);
void <a href="#classboost_1_1circular__buffer_17485ee7f58b01363170114f2123a48d7">erase_end</a>(size_type n);
void <a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear</a>();
};
@@ -592,7 +597,18 @@ template &lt;class T, class Alloc&gt;
</p>
<p>
The debug support is enabled only in the debug mode (when the <code>NDEBUG</code> is not defined). It can also be
explicitly disabled by defining <code>BOOST_CB_DISABLE_DEBUG</code> macro.
explicitly disabled (only for <code>circular_buffer</code>) by defining <code>BOOST_CB_DISABLE_DEBUG</code>
macro.
</p>
<h2>
<a name="intreprocess" id="interprocess">Compatibility with Interprocess library</a>
</h2>
<p>
The <code>circular_buffer</code> is compatible with the <a href="../../../doc/html/interprocess.html">Boost
Interprocess</a> library used for interprocess communication. Considering that the <code>circular_buffer</code>'s
debug support relies on 'raw' pointers - which is not permited by the Interprocess library - the code has to
compiled with <code>-DBOOST_CB_DISABLE_DEBUG</code> or <code>-DNDEBUG</code> (which disables the
<a href="#debug">Debug Support</a>). Not doing that will cause the compilation to fail.
</p>
<h2>
<a name="examples" id="examples">More Examples</a>
@@ -667,6 +683,7 @@ template &lt;class T, class Alloc&gt;
#include &lt;boost/thread/mutex.hpp&gt;
#include &lt;boost/thread/condition.hpp&gt;
#include &lt;boost/thread/thread.hpp&gt;
#include &lt;boost/call_traits.hpp&gt;
#include &lt;boost/progress.hpp&gt;
#include &lt;boost/bind.hpp&gt;
@@ -677,10 +694,13 @@ template &lt;class T, class Alloc&gt;
typedef boost::circular_buffer&lt;T&gt; container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits&lt;value_type&gt;::param_type param_type;
explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}
void push_front(const value_type&amp; item) {
void push_front(boost::call_traits&lt;value_type&gt;::param_type item) {
// param_type represents the "best" way to pass a parameter of type value_type to a method
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&amp;bounded_buffer&lt;value_type&gt;::is_not_full, this));
m_container.push_front(item);
@@ -712,8 +732,9 @@ template &lt;class T, class Alloc&gt;
};
</pre>
<p>
The <code>bounded_buffer</code> uses <a href="../../thread/doc/">Boost Threads</a> and <a href=
"../../bind/bind.html">Boost Bind</a> libraries.
The <code>bounded_buffer</code> relies on <a href="../../thread/doc/">Boost Threads</a> and <a href=
"../../bind/bind.html">Boost Bind</a> libraries and <a href="../../utility/call_traits.htm">Boost call_traits</a>
utility.
</p>
<p>
The <code>push_front()</code> method is called by the producer thread in order to insert a new item into the
@@ -744,8 +765,8 @@ template &lt;class T, class Alloc&gt;
For comparison of bounded buffers based on different containers compile and run <a href=
"../test/bounded_buffer_comparison.cpp">bounded_buffer_comparison.cpp</a>. The test should reveal the bounded
buffer based on the <code>circular_buffer</code> is most effective closely followed by the
<code>std::deque</code> based bounded buffer. (In praxis the result may be different because the test is affected
by external factors such as immediate CPU load.)
<code>std::deque</code> based bounded buffer. (In reality the result may differ sometimes because the test is
always affected by external factors such as immediate CPU load.)
</p>
<h2>
<a name="header" id="header">Header Files</a>
@@ -1069,7 +1090,7 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href=
"#classboost_1_1circular__buffer_1862a64cbc6a49376ecbb8321c3b44974">circular_buffer(capacity_type,
"#classboost_1_1circular__buffer_18f1606a26fead923c2cbe068a74e28b6">circular_buffer(capacity_type,
const allocator_type&amp; alloc)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_161714204ef5172d156e2c7eccd04998f">set_capacity(capacity_type)</a></code>
</dd>
@@ -1078,12 +1099,12 @@ template &lt;class T, class Alloc&gt;
</tr>
<tr>
<td>
<a id="classboost_1_1circular__buffer_1862a64cbc6a49376ecbb8321c3b44974" name=
"classboost_1_1circular__buffer_1862a64cbc6a49376ecbb8321c3b44974"></a><code><b>explicit
<a id="classboost_1_1circular__buffer_18f1606a26fead923c2cbe068a74e28b6" name=
"classboost_1_1circular__buffer_18f1606a26fead923c2cbe068a74e28b6"></a><code><b>explicit
circular_buffer(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> capacity, const
<a href="#classboost_1_1circular__buffer_14e07c6ddfe89debe384e59bed06e7cb7">allocator_type</a>&amp; alloc =
allocator_type());</b></code><br>
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> buffer_capacity,
const <a href="#classboost_1_1circular__buffer_14e07c6ddfe89debe384e59bed06e7cb7">allocator_type</a>&amp;
alloc = allocator_type());</b></code><br>
<br>
Create an empty <code>circular_buffer</code> with the specified capacity.
<dl>
@@ -1092,7 +1113,7 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href="#classboost_1_1circular__buffer_15ebab2b2538d733790b5752582728e77">capacity()</a> ==
capacity &amp;&amp; <a href=
buffer_capacity &amp;&amp; <a href=
"#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a> == 0</code>
</dd>
</dl>
@@ -1103,7 +1124,7 @@ template &lt;class T, class Alloc&gt;
<dd>
<dl compact>
<dt>
<code>capacity</code>
<code>buffer_capacity</code>
</dt>
<dd>
The maximum number of elements which can be stored in the <code>circular_buffer</code>.
@@ -1221,10 +1242,10 @@ template &lt;class T, class Alloc&gt;
</tr>
<tr>
<td>
<a id="classboost_1_1circular__buffer_10c7e9286d8270357d7e369b183124239" name=
"classboost_1_1circular__buffer_10c7e9286d8270357d7e369b183124239"></a><code><b>circular_buffer(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> capacity, <a href=
"#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n, <a href=
<a id="classboost_1_1circular__buffer_104dc644486d835b56aa479ec48b52230" name=
"classboost_1_1circular__buffer_104dc644486d835b56aa479ec48b52230"></a><code><b>circular_buffer(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> buffer_capacity,
<a href="#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n, <a href=
"#classboost_1_1circular__buffer_1a8397191092f5bacee991b623ca4b910">const_reference</a> item, const
<a href="#classboost_1_1circular__buffer_14e07c6ddfe89debe384e59bed06e7cb7">allocator_type</a>&amp; alloc =
allocator_type());</b></code><br>
@@ -1236,7 +1257,7 @@ template &lt;class T, class Alloc&gt;
<b>Precondition:</b>
</dt>
<dd>
<code>capacity &gt;= n</code>
<code>buffer_capacity &gt;= n</code>
</dd>
</dl>
<dl>
@@ -1245,7 +1266,7 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href="#classboost_1_1circular__buffer_15ebab2b2538d733790b5752582728e77">capacity()</a> ==
capacity &amp;&amp; <a href=
buffer_capacity &amp;&amp; <a href=
"#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a> == n &amp;&amp;
(*this)[0] == item &amp;&amp; (*this)[1] == item &amp;&amp; ... &amp;&amp; (*this)[n - 1] ==
item</code>
@@ -1258,7 +1279,7 @@ template &lt;class T, class Alloc&gt;
<dd>
<dl compact>
<dt>
<code>capacity</code>
<code>buffer_capacity</code>
</dt>
<dd>
The capacity of the created <code>circular_buffer</code>.
@@ -1464,11 +1485,11 @@ template &lt;class T, class Alloc&gt;
</tr>
<tr>
<td>
<a id="classboost_1_1circular__buffer_1a64dcad327971194a706d52487151eb7" name=
"classboost_1_1circular__buffer_1a64dcad327971194a706d52487151eb7"></a> <code><b>template &lt;class
<a id="classboost_1_1circular__buffer_1a851f75f4a85b1a2b1a241904d21503f" name=
"classboost_1_1circular__buffer_1a851f75f4a85b1a2b1a241904d21503f"></a> <code><b>template &lt;class
InputIterator&gt;<br>
circular_buffer(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> capacity,
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> buffer_capacity,
InputIterator first, InputIterator last, const <a href=
"#classboost_1_1circular__buffer_14e07c6ddfe89debe384e59bed06e7cb7">allocator_type</a>&amp; alloc =
allocator_type());</b></code><br>
@@ -1490,14 +1511,15 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href="#classboost_1_1circular__buffer_15ebab2b2538d733790b5752582728e77">capacity()</a> ==
capacity &amp;&amp; <a href=
buffer_capacity &amp;&amp; <a href=
"#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a> &lt;=
std::distance(first, last) &amp;&amp; (*this)[0]== *(last - capacity) &amp;&amp; (*this)[1] == *(last -
capacity + 1) &amp;&amp; ... &amp;&amp; (*this)[capacity - 1] == *(last - 1)</code><br>
std::distance(first, last) &amp;&amp; (*this)[0]== *(last - buffer_capacity) &amp;&amp; (*this)[1] ==
*(last - buffer_capacity + 1) &amp;&amp; ... &amp;&amp; (*this)[buffer_capacity - 1] == *(last -
1)</code><br>
<br>
If the number of items to be copied from the range <code>[first, last)</code> is greater than the
specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
will be copied.
specified <code>buffer_capacity</code> then only elements from the range <code>[last - buffer_capacity,
last)</code> will be copied.
</dd>
</dl>
<dl>
@@ -1507,7 +1529,7 @@ template &lt;class T, class Alloc&gt;
<dd>
<dl compact>
<dt>
<code>capacity</code>
<code>buffer_capacity</code>
</dt>
<dd>
The capacity of the created <code>circular_buffer</code>.
@@ -1601,7 +1623,7 @@ template &lt;class T, class Alloc&gt;
<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>
@@ -2491,7 +2513,7 @@ template &lt;class T, class Alloc&gt;
<b>See Also:</b>
</dt>
<dd>
<code>operator[]</code>
<code><a href="#classboost_1_1circular__buffer_1d219f0d3203fb43b964a8cf63f1865cd">operator[]</a></code>
</dd>
</dl>
</td>
@@ -3420,7 +3442,7 @@ template &lt;class T, class Alloc&gt;
<b>Complexity:</b>
</dt>
<dd>
Linear (in <code>std::min(m, n)</code>); constant if the <code>circular_buffer</code> is full.
Linear (in <code>(std::min)(m, n)</code>); constant if the <code>circular_buffer</code> is full.
</dd>
</dl>
<dl>
@@ -4274,11 +4296,11 @@ template &lt;class T, class Alloc&gt;
<dd>
<code><a href="#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca">assign(capacity_type, size_type,
"#classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a">assign(capacity_type, size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1253302d9bda5d7efbc4a6c311de3790c">assign(InputIterator,
InputIterator)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6">assign(capacity_type,
"#classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366">assign(capacity_type,
InputIterator, InputIterator)</a></code>
</dd>
</dl>
@@ -4375,12 +4397,12 @@ template &lt;class T, class Alloc&gt;
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
"#classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca">assign(capacity_type, size_type,
const_reference)</a></code>, <code><a href=
<code><a href="#classboost_1_1circular__buffer_1db1558911b2e251a587aeb3d8b3d797d">operator=</a></code>,
<code><a href="#classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a">assign(capacity_type,
size_type, const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1253302d9bda5d7efbc4a6c311de3790c">assign(InputIterator,
InputIterator)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6">assign(capacity_type,
"#classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366">assign(capacity_type,
InputIterator, InputIterator)</a></code>
</dd>
</dl>
@@ -4388,10 +4410,10 @@ template &lt;class T, class Alloc&gt;
</tr>
<tr>
<td>
<a id="classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca" name=
"classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca"></a><code><b>void assign(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> capacity, <a href=
"#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n, <a href=
<a id="classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a" name=
"classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a"></a><code><b>void assign(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> buffer_capacity,
<a href="#classboost_1_1circular__buffer_19ba12c0142a21a7d960877c22fa3ea00">size_type</a> n, <a href=
"#classboost_1_1circular__buffer_1a8397191092f5bacee991b623ca4b910">const_reference</a>
item);</b></code><br>
<br>
@@ -4415,7 +4437,7 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href="#classboost_1_1circular__buffer_15ebab2b2538d733790b5752582728e77">capacity()</a> ==
capacity &amp;&amp; <a href=
buffer_capacity &amp;&amp; <a href=
"#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a> == n &amp;&amp;
(*this)[0] == item &amp;&amp; (*this)[1] == item &amp;&amp; ... &amp;&amp; (*this) [n - 1] ==
item</code>
@@ -4428,7 +4450,7 @@ template &lt;class T, class Alloc&gt;
<dd>
<dl compact>
<dt>
<code>capacity</code>
<code>buffer_capacity</code>
</dt>
<dd>
The new capacity.
@@ -4498,12 +4520,12 @@ template &lt;class T, class Alloc&gt;
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
"#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
<code><a href="#classboost_1_1circular__buffer_1db1558911b2e251a587aeb3d8b3d797d">operator=</a></code>,
<code><a href="#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1253302d9bda5d7efbc4a6c311de3790c">assign(InputIterator,
InputIterator)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6">assign(capacity_type,
"#classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366">assign(capacity_type,
InputIterator, InputIterator)</a></code>
</dd>
</dl>
@@ -4610,12 +4632,12 @@ template &lt;class T, class Alloc&gt;
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
"#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
<code><a href="#classboost_1_1circular__buffer_1db1558911b2e251a587aeb3d8b3d797d">operator=</a></code>,
<code><a href="#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca">assign(capacity_type, size_type,
"#classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a">assign(capacity_type, size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6">assign(capacity_type,
"#classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366">assign(capacity_type,
InputIterator, InputIterator)</a></code>
</dd>
</dl>
@@ -4623,11 +4645,11 @@ template &lt;class T, class Alloc&gt;
</tr>
<tr>
<td>
<a id="classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6" name=
"classboost_1_1circular__buffer_11edb80acdf1f7f1df8217d57256e41f6"></a> <code><b>template &lt;class
<a id="classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366" name=
"classboost_1_1circular__buffer_127cab6034beeeb0e11863c8c14d14366"></a> <code><b>template &lt;class
InputIterator&gt;<br>
void assign(<a href=
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> capacity,
"#classboost_1_1circular__buffer_1dc642ff2be4db0be1a457810e5d09595">capacity_type</a> buffer_capacity,
InputIterator first, InputIterator last);</b></code><br>
<br>
Assign a copy of the range into the <code>circular_buffer</code> specifying the capacity.
@@ -4652,14 +4674,15 @@ template &lt;class T, class Alloc&gt;
</dt>
<dd>
<code><a href="#classboost_1_1circular__buffer_15ebab2b2538d733790b5752582728e77">capacity()</a> ==
capacity &amp;&amp; <a href=
buffer_capacity &amp;&amp; <a href=
"#classboost_1_1circular__buffer_15fa0edd153e2591dd6bf070eb663ee32">size()</a> &lt;=
std::distance(first, last) &amp;&amp; (*this)[0]== *(last - capacity) &amp;&amp; (*this)[1] == *(last -
capacity + 1) &amp;&amp; ... &amp;&amp; (*this)[capacity - 1] == *(last - 1)</code><br>
std::distance(first, last) &amp;&amp; (*this)[0]== *(last - buffer_capacity) &amp;&amp; (*this)[1] ==
*(last - buffer_capacity + 1) &amp;&amp; ... &amp;&amp; (*this)[buffer_capacity - 1] == *(last -
1)</code><br>
<br>
If the number of items to be copied from the range <code>[first, last)</code> is greater than the
specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
will be copied.
specified <code>buffer_capacity</code> then only elements from the range <code>[last - buffer_capacity,
last)</code> will be copied.
</dd>
</dl>
<dl>
@@ -4669,7 +4692,7 @@ template &lt;class T, class Alloc&gt;
<dd>
<dl compact>
<dt>
<code>capacity</code>
<code>buffer_capacity</code>
</dt>
<dd>
The new capacity.
@@ -4741,10 +4764,10 @@ template &lt;class T, class Alloc&gt;
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
"#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
<code><a href="#classboost_1_1circular__buffer_1db1558911b2e251a587aeb3d8b3d797d">operator=</a></code>,
<code><a href="#classboost_1_1circular__buffer_19ba4a81df16f386d31b04b49c82d1ada">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1aa10b4e4ec1f1c5918931b04b31d43ca">assign(capacity_type, size_type,
"#classboost_1_1circular__buffer_1dbebb80a5f38e52a37ec9f3ed765600a">assign(capacity_type, size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer_1253302d9bda5d7efbc4a6c311de3790c">assign(InputIterator,
InputIterator)</a></code>
@@ -6103,7 +6126,10 @@ template &lt;class T, class Alloc&gt;
"#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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
</dd>
</dl>
</td>
@@ -6215,7 +6241,10 @@ template &lt;class T, class Alloc&gt;
"#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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
</dd>
</dl>
</td>
@@ -6328,7 +6357,10 @@ template &lt;class T, class Alloc&gt;
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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
</dd>
</dl>
</td>
@@ -6453,6 +6485,219 @@ template &lt;class T, class Alloc&gt;
<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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></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><a href="#classboost_1_1circular__buffer_1826f5770a40b8b752eb9587378464d1e">clear()</a></code>
</dd>
</dl>
@@ -6504,7 +6749,7 @@ template &lt;class T, class Alloc&gt;
<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>
@@ -6520,7 +6765,10 @@ template &lt;class T, class Alloc&gt;
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>
@@ -7116,6 +7364,23 @@ template &lt;class T, class Alloc&gt;
<a name="relnotes" id="relnotes">Release Notes</a>
</h2>
<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

View File

@@ -1304,13 +1304,9 @@ public:
<dd>
To explicitly clear the extra allocated memory use the <b>shrink-to-fit</b> technique:<br>
<br>
<code><a href=
"circular_buffer.html#namespaceboost">boost</a>::circular_buffer_space_optimized&lt;int&gt;
cb(1000);<br>
<code>boost::circular_buffer_space_optimized&lt;int&gt; cb(1000);<br>
...<br>
<a href=
"circular_buffer.html#namespaceboost">boost</a>::circular_buffer_space_optimized&lt;int&gt;(cb).swap(cb);</code><br>
boost::circular_buffer_space_optimized&lt;int&gt;(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</a>.
@@ -1849,7 +1845,9 @@ public:
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_177e35432c5e69b7a16ef7d937950e7a8">operator=</a></code>,
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_1108055ae3f6b1635e1428b0455902cbf">assign(capacity_type,
size_type, const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer__space__optimized_1417de2c2419c44d83a92c463762df5fb">assign(InputIterator,
@@ -1979,7 +1977,9 @@ public:
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_177e35432c5e69b7a16ef7d937950e7a8">operator=</a></code>,
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_17ca4fda9526d0dad99706763c3b2d9f1">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer__space__optimized_1417de2c2419c44d83a92c463762df5fb">assign(InputIterator,
@@ -2097,7 +2097,9 @@ public:
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_177e35432c5e69b7a16ef7d937950e7a8">operator=</a></code>,
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_17ca4fda9526d0dad99706763c3b2d9f1">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer__space__optimized_1108055ae3f6b1635e1428b0455902cbf">assign(capacity_type,
@@ -2233,7 +2235,9 @@ public:
<b>See Also:</b>
</dt>
<dd>
<code>operator=</code>, <code><a href=
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_177e35432c5e69b7a16ef7d937950e7a8">operator=</a></code>,
<code><a href=
"#classboost_1_1circular__buffer__space__optimized_17ca4fda9526d0dad99706763c3b2d9f1">assign(size_type,
const_reference)</a></code>, <code><a href=
"#classboost_1_1circular__buffer__space__optimized_1108055ae3f6b1635e1428b0455902cbf">assign(capacity_type,

View File

@@ -68,7 +68,7 @@ http://www.boost.org/LICENSE_1_0.txt)
</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 @@ http://www.boost.org/LICENSE_1_0.txt)
</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>

View File

@@ -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 @@ public:
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);
@@ -709,7 +710,7 @@ public:
iterators pointing to the first <code>n</code> elements; does not invalidate any iterators if the
<code>circular_buffer</code> is full.
\par Complexity
Linear (in <code>std::min(m, n)</code>); constant if the <code>circular_buffer</code> is full.
Linear (in <code>(std::min)(m, n)</code>); constant if the <code>circular_buffer</code> is full.
\sa <code><a href="http://www.sgi.com/tech/stl/rotate.html">std::rotate</a></code>
*/
void rotate(const_iterator new_begin) {
@@ -998,17 +999,17 @@ public:
//! Create an empty <code>circular_buffer</code> with the specified capacity.
/*!
\post <code>capacity() == capacity \&\& size() == 0</code>
\param capacity The maximum number of elements which can be stored in the <code>circular_buffer</code>.
\post <code>capacity() == buffer_capacity \&\& size() == 0</code>
\param buffer_capacity The maximum number of elements which can be stored in the <code>circular_buffer</code>.
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\par Complexity
Constant.
*/
explicit circular_buffer(capacity_type capacity, const allocator_type& alloc = allocator_type())
explicit circular_buffer(capacity_type buffer_capacity, const allocator_type& alloc = allocator_type())
: m_size(0), m_alloc(alloc) {
initialize_buffer(capacity);
initialize_buffer(buffer_capacity);
m_first = m_last = m_buff;
}
@@ -1033,10 +1034,10 @@ public:
/*! \brief Create a <code>circular_buffer</code> with the specified capacity and filled with <code>n</code>
copies of <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>
\param capacity The capacity of the created <code>circular_buffer</code>.
\pre <code>buffer_capacity >= n</code>
\post <code>capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
\&\& ... \&\& (*this)[n - 1] == item</code>
\param buffer_capacity The capacity of the created <code>circular_buffer</code>.
\param n The number of elements the created <code>circular_buffer</code> will be filled with.
\param item The element the created <code>circular_buffer</code> will be filled with.
\param alloc The allocator.
@@ -1046,13 +1047,13 @@ public:
\par Complexity
Linear (in the <code>n</code>).
*/
circular_buffer(capacity_type capacity, size_type n, param_value_type item,
circular_buffer(capacity_type buffer_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
initialize_buffer(capacity, item);
BOOST_CB_ASSERT(buffer_capacity >= size()); // check for capacity lower than size
initialize_buffer(buffer_capacity, item);
m_first = m_buff;
m_last = capacity == n ? m_buff : m_buff + n;
m_last = buffer_capacity == n ? m_buff : m_buff + n;
}
//! The copy constructor.
@@ -1067,7 +1068,11 @@ public:
Linear (in the size of <code>cb</code>).
*/
circular_buffer(const circular_buffer<T, Alloc>& cb)
: m_size(cb.size()), m_alloc(cb.get_allocator()) {
:
#if BOOST_CB_ENABLE_DEBUG
debug_iterator_registry(),
#endif
m_size(cb.size()), m_alloc(cb.get_allocator()) {
initialize_buffer(cb.capacity());
m_first = m_buff;
BOOST_TRY {
@@ -1126,13 +1131,13 @@ public:
\pre Valid range <code>[first, last)</code>.<br>
<code>first</code> and <code>last</code> have to meet the requirements of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
\post <code>capacity() == capacity \&\& size() \<= std::distance(first, last) \&\&
(*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
(*this)[capacity - 1] == *(last - 1)</code><br><br>
\post <code>capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\&
(*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\&
(*this)[buffer_capacity - 1] == *(last - 1)</code><br><br>
If the number of items to be copied from the range <code>[first, last)</code> is greater than the
specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
will be copied.
\param capacity The capacity of the created <code>circular_buffer</code>.
specified <code>buffer_capacity</code> then only elements from the range
<code>[last - buffer_capacity, last)</code> will be copied.
\param buffer_capacity The capacity of the created <code>circular_buffer</code>.
\param first The beginning of the range to be copied.
\param last The end of the range to be copied.
\param alloc The allocator.
@@ -1145,10 +1150,10 @@ public:
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
*/
template <class InputIterator>
circular_buffer(capacity_type capacity, InputIterator first, InputIterator last,
circular_buffer(capacity_type buffer_capacity, InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type())
: m_alloc(alloc) {
initialize(capacity, first, last, is_integral<InputIterator>());
initialize(buffer_capacity, first, last, is_integral<InputIterator>());
}
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
@@ -1161,7 +1166,7 @@ public:
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() {
@@ -1227,7 +1232,8 @@ public:
<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>
@@ -1241,9 +1247,9 @@ public:
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
\post <code>capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
\&\& ... \&\& (*this) [n - 1] == item </code>
\param capacity The new capacity.
\param buffer_capacity The new capacity.
\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.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
@@ -1256,13 +1262,14 @@ public:
<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 capacity, size_type n, param_value_type item) {
BOOST_CB_ASSERT(capacity >= n); // check for new capacity lower than n
assign_n(capacity, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, m_alloc));
void assign(capacity_type buffer_capacity, size_type n, param_value_type item) {
BOOST_CB_ASSERT(buffer_capacity >= n); // check for new capacity lower than n
assign_n(buffer_capacity, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, m_alloc));
}
//! Assign a copy of the range into the <code>circular_buffer</code>.
@@ -1287,8 +1294,8 @@ public:
<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>
@@ -1305,13 +1312,13 @@ public:
\pre Valid range <code>[first, last)</code>.<br>
<code>first</code> and <code>last</code> have to meet the requirements of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
\post <code>capacity() == capacity \&\& size() \<= std::distance(first, last) \&\&
(*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
(*this)[capacity - 1] == *(last - 1)</code><br><br>
\post <code>capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\&
(*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\&
(*this)[buffer_capacity - 1] == *(last - 1)</code><br><br>
If the number of items to be copied from the range <code>[first, last)</code> is greater than the
specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
will be copied.
\param capacity The new capacity.
specified <code>buffer_capacity</code> then only elements from the range
<code>[last - buffer_capacity, last)</code> will be copied.
\param buffer_capacity The new capacity.
\param first The beginning of the range to be copied.
\param last The end of the range to be copied.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
@@ -1326,15 +1333,15 @@ public:
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>
*/
template <class InputIterator>
void assign(capacity_type capacity, InputIterator first, InputIterator last) {
assign(capacity, first, last, is_integral<InputIterator>());
void assign(capacity_type buffer_capacity, InputIterator first, InputIterator last) {
assign(buffer_capacity, first, last, is_integral<InputIterator>());
}
//! Swap the contents of two <code>circular_buffer</code>s.
@@ -1801,7 +1808,8 @@ public:
\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
@@ -1838,7 +1846,7 @@ public:
\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
@@ -1877,7 +1885,8 @@ public:
<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
@@ -1917,7 +1926,7 @@ public:
<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
@@ -1943,6 +1952,70 @@ public:
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>
@@ -1953,9 +2026,10 @@ public:
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();
@@ -2062,6 +2136,20 @@ private:
//! 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);
}
@@ -2079,14 +2167,14 @@ private:
}
//! Initialize the internal buffer.
void initialize_buffer(capacity_type capacity) {
m_buff = allocate(capacity);
m_end = m_buff + capacity;
void initialize_buffer(capacity_type buffer_capacity) {
m_buff = allocate(buffer_capacity);
m_end = m_buff + buffer_capacity;
}
//! Initialize the internal buffer.
void initialize_buffer(capacity_type capacity, param_value_type item) {
initialize_buffer(capacity);
void initialize_buffer(capacity_type buffer_capacity, param_value_type item) {
initialize_buffer(buffer_capacity);
BOOST_TRY {
cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, m_alloc);
} BOOST_CATCH(...) {
@@ -2135,35 +2223,35 @@ private:
//! Specialized initialize method.
template <class IntegralType>
void initialize(capacity_type capacity, IntegralType n, IntegralType item, const true_type&) {
BOOST_CB_ASSERT(capacity >= static_cast<size_type>(n)); // check for capacity lower than n
void initialize(capacity_type buffer_capacity, IntegralType n, IntegralType item, const true_type&) {
BOOST_CB_ASSERT(buffer_capacity >= static_cast<size_type>(n)); // check for capacity lower than n
m_size = static_cast<size_type>(n);
initialize_buffer(capacity, item);
initialize_buffer(buffer_capacity, item);
m_first = m_buff;
m_last = capacity == size() ? m_buff : m_buff + size();
m_last = buffer_capacity == size() ? m_buff : m_buff + size();
}
//! Specialized initialize method.
template <class Iterator>
void initialize(capacity_type capacity, Iterator first, Iterator last, const false_type&) {
void initialize(capacity_type buffer_capacity, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
initialize(capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(buffer_capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
initialize(capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
//! Specialized initialize method.
template <class InputIterator>
void initialize(capacity_type capacity,
void initialize(capacity_type buffer_capacity,
InputIterator first,
InputIterator last,
const std::input_iterator_tag&) {
initialize_buffer(capacity);
initialize_buffer(buffer_capacity);
m_first = m_last = m_buff;
m_size = 0;
if (capacity == 0)
if (buffer_capacity == 0)
return;
while (first != last && !full()) {
m_alloc.construct(m_last, *first++);
@@ -2179,32 +2267,32 @@ private:
//! Specialized initialize method.
template <class ForwardIterator>
void initialize(capacity_type capacity,
void initialize(capacity_type buffer_capacity,
ForwardIterator first,
ForwardIterator last,
const std::forward_iterator_tag&) {
BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
initialize(capacity, first, last, std::distance(first, last));
initialize(buffer_capacity, first, last, std::distance(first, last));
}
//! Initialize the circular buffer.
template <class ForwardIterator>
void initialize(capacity_type capacity,
void initialize(capacity_type buffer_capacity,
ForwardIterator first,
ForwardIterator last,
size_type distance) {
initialize_buffer(capacity);
initialize_buffer(buffer_capacity);
m_first = m_buff;
if (distance > capacity) {
std::advance(first, distance - capacity);
m_size = capacity;
if (distance > buffer_capacity) {
std::advance(first, distance - buffer_capacity);
m_size = buffer_capacity;
} else {
m_size = distance;
}
BOOST_TRY {
m_last = cb_details::uninitialized_copy_with_alloc(first, last, m_buff, m_alloc);
} BOOST_CATCH(...) {
deallocate(m_buff, capacity);
deallocate(m_buff, buffer_capacity);
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -2560,6 +2648,30 @@ private:
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

View File

@@ -146,9 +146,9 @@ class capacity_control {
public:
//! Constructor.
capacity_control(Size capacity, Size min_capacity = 0)
: m_capacity(capacity), m_min_capacity(min_capacity) {
BOOST_CB_ASSERT(capacity >= min_capacity); // check for capacity lower than min_capacity
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) {
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); // check for capacity lower than min_capacity
}
// Default copy constructor.

View File

@@ -189,9 +189,9 @@ public:
\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</a>.
\sa <code>rset_capacity(const capacity_type&)</code>,
@@ -513,6 +513,12 @@ public:
*/
~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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 <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_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>
@@ -1229,8 +1237,8 @@ private:
}
//! Ensure the reserve for possible growth up.
size_type ensure_reserve(size_type new_capacity, size_type size) const {
if (size + new_capacity / 5 >= new_capacity)
size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const {
if (buffer_size + new_capacity / 5 >= new_capacity)
new_capacity *= 2; // ensure at least 20% reserve
if (new_capacity > m_capacity_ctrl)
return m_capacity_ctrl;
@@ -1252,11 +1260,7 @@ private:
ensure_reserve(new_capacity, new_size));
}
#if BOOST_CB_ENABLE_DEBUG
# if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006))
this->invalidate_iterators_except(end());
# else
invalidate_iterators_except(end());
# endif
#endif
}
@@ -1276,11 +1280,7 @@ private:
circular_buffer<T, Alloc>::set_capacity(
ensure_reserve(new_capacity, size()));
#if BOOST_CB_ENABLE_DEBUG
# if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006))
this->invalidate_iterators_except(end());
# else
invalidate_iterators_except(end());
# endif
#endif
}

View File

@@ -6,12 +6,25 @@
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Added warning supression Paul A. Bristow 25 Nov 2008
# Bring in rules for testing.
import testing ;
project
: requirements
<toolset>msvc:<warnings>all
<toolset>msvc:<asynch-exceptions>on
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
<toolset>msvc:<cxxflags>/wd4996 # 'function': was declared deprecated
<toolset>msvc:<cxxflags>/wd4244 # conversion from 'int' to 'unsigned short', possible loss of data
# in date-time
;
test-suite "circular_buffer"
: [ 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 : ]
;

View File

@@ -12,6 +12,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/call_traits.hpp>
#include <boost/progress.hpp>
#include <boost/bind.hpp>
#include <deque>
@@ -29,10 +30,11 @@ public:
typedef boost::circular_buffer<T> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits<value_type>::param_type param_type;
explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}
void push_front(const value_type& item) {
void push_front(param_type item) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this));
m_container.push_front(item);
@@ -70,10 +72,11 @@ public:
typedef boost::circular_buffer_space_optimized<T> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits<value_type>::param_type param_type;
explicit bounded_buffer_space_optimized(size_type capacity) : m_container(capacity) {}
void push_front(const value_type& item) {
void push_front(param_type item) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_full, this));
m_container.push_front(item);
@@ -111,10 +114,11 @@ public:
typedef std::deque<T> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits<value_type>::param_type param_type;
explicit bounded_buffer_deque_based(size_type capacity) : m_capacity(capacity) {}
void push_front(const value_type& item) {
void push_front(param_type item) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_full, this));
m_container.push_front(item);
@@ -153,10 +157,11 @@ public:
typedef std::list<T> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits<value_type>::param_type param_type;
explicit bounded_buffer_list_based(size_type capacity) : m_capacity(capacity) {}
void push_front(const value_type& item) {
void push_front(param_type item) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_full, this));
m_container.push_front(item);

View File

@@ -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;
}