summaryrefslogtreecommitdiff
path: root/boost/circular_buffer/space_optimized.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/circular_buffer/space_optimized.hpp')
-rw-r--r--boost/circular_buffer/space_optimized.hpp520
1 files changed, 407 insertions, 113 deletions
diff --git a/boost/circular_buffer/space_optimized.hpp b/boost/circular_buffer/space_optimized.hpp
index 9c76afe7a5..688ab95796 100644
--- a/boost/circular_buffer/space_optimized.hpp
+++ b/boost/circular_buffer/space_optimized.hpp
@@ -1,6 +1,8 @@
// Implementation of the circular buffer adaptor.
// Copyright (c) 2003-2008 Jan Gaspar
+// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation.
+// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,7 +11,7 @@
#if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
#define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
-#if defined(_MSC_VER) && _MSC_VER >= 1200
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -20,10 +22,9 @@ namespace boost {
/*!
\class circular_buffer_space_optimized
- \brief Space optimized circular buffer container adaptor.
-
- For detailed documentation of the space_optimized_circular_buffer visit:
- http://www.boost.org/libs/circular_buffer/doc/space_optimized.html
+ \brief Space optimized circular buffer container adaptor.
+ <code>T</code> must be a copyable class or must have an noexcept move constructor
+ and move assignment operator.
*/
template <class T, class Alloc>
class circular_buffer_space_optimized :
@@ -51,29 +52,53 @@ public:
typedef typename circular_buffer<T, Alloc>::array_range array_range;
typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range;
typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type;
- typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
+ typedef typename circular_buffer<T, Alloc>::rvalue_type rvalue_type;
+ //typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
- //! Capacity controller of the space optimized circular buffer.
- /*!
- <p><pre>
-class capacity_control {
- size_type m_capacity;
- size_type m_min_capacity;
-public:
- capacity_control(size_type capacity, size_type min_capacity = 0) : m_capacity(capacity), m_min_capacity(min_capacity) {};
- size_type %capacity() const { return m_capacity; }
- size_type min_capacity() const { return m_min_capacity; }
- operator size_type() const { return m_capacity; }
-};</pre></p>
- \pre <code>capacity >= min_capacity</code>
- <p>The <code>capacity()</code> represents the capacity of the <code>circular_buffer_space_optimized</code> and
- the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.</p>
- <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
- <code>size_type</code>-like types which ensures compatibility of creating an instance of the
- <code>circular_buffer_space_optimized</code> with other STL containers. On the other hand the operator
- <code>%size_type()</code> provides implicit conversion to the <code>size_type</code> which allows to treat the
- capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
- <code><a href="circular_buffer.html">circular_buffer</a></code>.</p>
+/* <pre> is not passed through to html or pdf. So <br> is used in code section below. Ugly :-(
+Ideally want a link to capacity_control, but this would require include details
+and this would expose all the functions in details.
+There must be a better way of doing this.
+*/
+
+ /*! Capacity controller of the space optimized circular buffer.
+
+ \see capacity_control in details.hpp.
+<p>
+<code>
+class capacity_control<br>
+{<br>
+ size_type m_capacity; // Available capacity.<br>
+ size_type m_min_capacity; // Minimum capacity.<br>
+public:<br>
+ capacity_control(size_type capacity, size_type min_capacity = 0)<br>
+ : m_capacity(capacity), m_min_capacity(min_capacity)<br>
+ {};<br>
+ size_type %capacity() const { return m_capacity; }<br>
+ size_type min_capacity() const { return m_min_capacity; }<br>
+ operator size_type() const { return m_capacity; }<br>
+};<br>
+</code>
+</p>
+
+
+ <p>Always
+ <code>capacity >= min_capacity</code>.
+ </p>
+ <p>
+ The <code>capacity()</code> represents the capacity
+ of the <code>circular_buffer_space_optimized</code> and
+ the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.
+ </p>
+ <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
+ <code>size_type</code>-like types which ensures compatibility of creating an instance of the
+ <code>circular_buffer_space_optimized</code> with other STL containers.
+
+ On the other hand the operator <code>%size_type()</code>
+ provides implicit conversion to the <code>size_type</code> which allows to treat the
+ capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
+ <code>circular_buffer</a></code>.
+</p>
*/
typedef cb_details::capacity_control<size_type> capacity_type;
@@ -98,7 +123,7 @@ public:
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); }
- return_value_type operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
+ const_reference operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
#else
using circular_buffer<T, Alloc>::operator[];
#endif
@@ -125,7 +150,7 @@ public:
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>empty()</code>
*/
- bool full() const { return m_capacity_ctrl == size(); }
+ bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); }
/*! \brief Get the maximum number of elements which can be inserted into the
<code>circular_buffer_space_optimized</code> without overwriting any of already stored elements.
@@ -139,7 +164,7 @@ public:
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
*/
- size_type reserve() const { return m_capacity_ctrl - size(); }
+ size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); }
//! Get the capacity of the <code>circular_buffer_space_optimized</code>.
/*!
@@ -155,7 +180,7 @@ public:
\sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
<code>set_capacity(const capacity_type&)</code>
*/
- const capacity_type& capacity() const { return m_capacity_ctrl; }
+ const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; }
#if defined(BOOST_CB_TEST)
@@ -164,7 +189,7 @@ public:
\note This method is not intended to be used directly by the user.
It is defined only for testing purposes.
*/
- size_type internal_capacity() const { return circular_buffer<T, Alloc>::capacity(); }
+ size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer<T, Alloc>::capacity(); }
#endif // #if defined(BOOST_CB_TEST)
@@ -178,9 +203,9 @@ public:
than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
\param capacity_ctrl The new capacity controller.
- \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Strong.
\par Iterator Invalidation
@@ -222,7 +247,7 @@ public:
the requested size. (See the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -257,7 +282,7 @@ public:
\param capacity_ctrl The new capacity controller.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Strong.
\par Iterator Invalidation
@@ -293,7 +318,7 @@ public:
the requested size. (See the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -324,7 +349,7 @@ public:
\warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space
optimized circular buffer with zero capacity.
*/
- explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type())
+ explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
: circular_buffer<T, Alloc>(0, alloc)
, m_capacity_ctrl(0) {}
@@ -382,7 +407,7 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in the <code>n</code>).
*/
@@ -391,31 +416,6 @@ public:
: circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
, m_capacity_ctrl(capacity_ctrl) {}
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-
- /*! \cond */
- circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
- : circular_buffer<T, Alloc>(cb.begin(), cb.end())
- , m_capacity_ctrl(cb.m_capacity_ctrl) {}
-
- template <class InputIterator>
- circular_buffer_space_optimized(InputIterator first, InputIterator last)
- : circular_buffer<T, Alloc>(first, last)
- , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
-
- template <class InputIterator>
- circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last)
- : circular_buffer<T, Alloc>(
- init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
- first, last)
- , m_capacity_ctrl(capacity_ctrl) {
- reduce_capacity(
- is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
- }
- /*! \endcond */
-
-#else
-
//! The copy constructor.
/*!
Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
@@ -424,7 +424,7 @@ public:
\param cb The <code>circular_buffer_space_optimized</code> to be copied.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in the size of <code>cb</code>).
*/
@@ -432,6 +432,23 @@ public:
: circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
, m_capacity_ctrl(cb.m_capacity_ctrl) {}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ //! The move constructor.
+ /*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>,
+ leaving <code>cb</code> empty.
+ \pre C++ compiler with rvalue references support.
+ \post <code>cb.empty()</code>
+ \param cb <code>circular_buffer</code> to 'steal' value from.
+ \throws Nothing.
+ \par Constant.
+ */
+ circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
+ : circular_buffer<T, Alloc>()
+ , m_capacity_ctrl(0) {
+ cb.swap(*this);
+ }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
//! Create a full space optimized circular buffer filled with a copy of the range.
/*!
\pre Valid range <code>[first, last)</code>.<br>
@@ -446,7 +463,8 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept
+ and <code>InputIterator</code> is a move iterator.
\par Complexity
Linear (in the <code>std::distance(first, last)</code>).
*/
@@ -477,7 +495,7 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in <code>std::distance(first, last)</code>; in
<code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
@@ -491,11 +509,9 @@ public:
first, last, alloc)
, m_capacity_ctrl(capacity_ctrl) {
reduce_capacity(
- is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
+ is_same< BOOST_DEDUCED_TYPENAME iterator_category<InputIterator>::type, std::input_iterator_tag >());
}
-#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-
#if defined(BOOST_CB_NEVER_DEFINED)
// This section will never be compiled - the default destructor will be generated instead.
// Declared only for documentation purpose.
@@ -552,6 +568,24 @@ public:
return *this;
}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
+ \pre C++ compiler with rvalue references support.
+ \post <code>cb.empty()</code>
+ \param cb <code>circular_buffer</code> to 'steal' value from.
+ \throws Nothing.
+ \par Complexity
+ Constant.
+ */
+ circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
+ cb.swap(*this); // now `this` holds `cb`
+ circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
+ .swap(cb); // makes `cb` empty
+ return *this;
+ }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+
//! Assign <code>n</code> items into the space optimized circular buffer.
/*!
The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
@@ -563,7 +597,7 @@ public:
\param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -596,7 +630,7 @@ public:
\param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -630,7 +664,8 @@ public:
\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
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
+ <code>InputIterator</code> is a move iterator.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -670,7 +705,8 @@ public:
\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
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
+ <code>InputIterator</code> is a move iterator.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -692,7 +728,7 @@ public:
circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
}
- //! Swap the contents of two space optimized circular buffers.
+ //! Swap the contents of two space-optimized circular-buffers.
/*!
\post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
@@ -704,14 +740,18 @@ public:
\par Iterator Invalidation
Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
hand the iterators still point to the same elements but within another container. If you want to rely on
- this feature you have to turn the <a href="circular_buffer.html#debug">Debug Support</a> off otherwise an
- assertion will report an error if such invalidated iterator is used.)
+ this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
+ otherwise an assertion will report an error if such invalidated iterator is used.)
\par Complexity
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
- \sa <code>\link swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)
- swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)\endlink</code>
+ \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>,
+ <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
+
+
*/
- void swap(circular_buffer_space_optimized<T, Alloc>& cb) {
+ // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103.
+
+ void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
circular_buffer<T, Alloc>::swap(cb);
}
@@ -725,7 +765,7 @@ public:
\param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -736,11 +776,60 @@ public:
\sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
- void push_back(param_value_type item = value_type()) {
+ void push_back(param_value_type item) {
check_low_capacity();
circular_buffer<T, Alloc>::push_back(item);
}
+ //! Insert a new element at the end of the space optimized circular buffer.
+ /*!
+ \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
+ If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
+ capacity is <code>0</code>, nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param item The element to be inserted.
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
+ <code>pop_front()</code>
+ */
+ void push_back(rvalue_type item) {
+ check_low_capacity();
+ circular_buffer<T, Alloc>::push_back(boost::move(item));
+ }
+
+ //! Insert a new element at the end of the space optimized circular buffer.
+ /*!
+ \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
+ If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
+ capacity is <code>0</code>, nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T()</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
+ <code>pop_front()</code>
+ */
+ void push_back() {
+ check_low_capacity();
+ circular_buffer<T, Alloc>::push_back();
+ }
+
//! Insert a new element at the beginning of the space optimized circular buffer.
/*!
\post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
@@ -750,7 +839,7 @@ public:
\param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -761,11 +850,61 @@ public:
\sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
- void push_front(param_value_type item = value_type()) {
+ void push_front(param_value_type item) {
check_low_capacity();
circular_buffer<T, Alloc>::push_front(item);
}
+ //! Insert a new element at the beginning of the space optimized circular buffer.
+ /*!
+ \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
+ If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
+ capacity is <code>0</code>, nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param item The element to be inserted.
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
+ <code>pop_front()</code>
+ */
+ void push_front(rvalue_type item) {
+ check_low_capacity();
+ circular_buffer<T, Alloc>::push_front(boost::move(item));
+ }
+
+ //! Insert a new element at the beginning of the space optimized circular buffer.
+ /*!
+ \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
+ If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
+ capacity is <code>0</code>, nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T()</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
+ <code>pop_front()</code>
+ */
+ void push_front() {
+ check_low_capacity();
+ circular_buffer<T, Alloc>::push_front();
+ }
+
//! Remove the last element from the space optimized circular buffer.
/*!
\pre <code>!empty()</code>
@@ -826,8 +965,8 @@ public:
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -843,12 +982,88 @@ public:
rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code>
*/
- iterator insert(iterator pos, param_value_type item = value_type()) {
+ iterator insert(iterator pos, param_value_type item) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::insert(begin() + index, item);
}
+ //! Insert an element at the specified position.
+ /*!
+ \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
+ end.
+ \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
+ If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
+ the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
+ <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
+ nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param pos An iterator specifying the position where the <code>item</code> will be inserted.
+ \param item The element to be inserted.
+ \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
+ the <i>Effect</i>.)
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link insert(iterator, size_type, param_value_type)
+ insert(iterator, size_type, value_type)\endlink</code>,
+ <code>insert(iterator, InputIterator, InputIterator)</code>,
+ <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
+ <code>\link rinsert(iterator, size_type, param_value_type)
+ rinsert(iterator, size_type, value_type)\endlink</code>,
+ <code>rinsert(iterator, InputIterator, InputIterator)</code>
+ */
+ iterator insert(iterator pos, rvalue_type item) {
+ size_type index = pos - begin();
+ check_low_capacity();
+ return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
+ }
+
+ //! Insert an element at the specified position.
+ /*!
+ \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
+ end.
+ \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
+ If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
+ the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
+ <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
+ nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param pos An iterator specifying the position where the <code>item</code> will be inserted.
+ \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
+ the <i>Effect</i>.)
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T()</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link insert(iterator, size_type, param_value_type)
+ insert(iterator, size_type, value_type)\endlink</code>,
+ <code>insert(iterator, InputIterator, InputIterator)</code>,
+ <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
+ <code>\link rinsert(iterator, size_type, param_value_type)
+ rinsert(iterator, size_type, value_type)\endlink</code>,
+ <code>rinsert(iterator, InputIterator, InputIterator)</code>
+ */
+ iterator insert(iterator pos) {
+ size_type index = pos - begin();
+ check_low_capacity();
+ return circular_buffer<T, Alloc>::insert(begin() + index);
+ }
+
//! Insert <code>n</code> copies of the <code>item</code> at the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
@@ -863,8 +1078,8 @@ public:
\param item The element whose copies will be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -876,7 +1091,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br>
- <code>p ---^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
+ <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
<code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
<code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
@@ -911,8 +1126,7 @@ public:
\param last The end of the range to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -927,7 +1141,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br>
- <code>p ---^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
+ <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
<code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
@@ -962,8 +1176,8 @@ public:
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -979,12 +1193,88 @@ public:
insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code>
*/
- iterator rinsert(iterator pos, param_value_type item = value_type()) {
+ iterator rinsert(iterator pos, param_value_type item) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
}
+ //! Insert an element before the specified position.
+ /*!
+ \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
+ end.
+ \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
+ If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
+ <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
+ <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
+ nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
+ \param item The element to be inserted.
+ \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
+ the <i>Effect</i>.)
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link rinsert(iterator, size_type, param_value_type)
+ rinsert(iterator, size_type, value_type)\endlink</code>,
+ <code>rinsert(iterator, InputIterator, InputIterator)</code>,
+ <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
+ <code>\link insert(iterator, size_type, param_value_type)
+ insert(iterator, size_type, value_type)\endlink</code>,
+ <code>insert(iterator, InputIterator, InputIterator)</code>
+ */
+ iterator rinsert(iterator pos, rvalue_type item) {
+ size_type index = pos - begin();
+ check_low_capacity();
+ return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
+ }
+
+ //! Insert an element before the specified position.
+ /*!
+ \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
+ end.
+ \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
+ If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
+ <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
+ <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
+ nothing will be inserted.<br><br>
+ The amount of allocated memory in the internal buffer may be predictively increased.
+ \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
+ \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
+ the <i>Effect</i>.)
+ \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
+ used).
+ Whatever <code>T::T()</code> throws.
+ Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
+ \par Exception Safety
+ Basic.
+ \par Iterator Invalidation
+ Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
+ equal to <code>end()</code>).
+ \par Complexity
+ Linear (in the size of the <code>circular_buffer_space_optimized</code>).
+ \sa <code>\link rinsert(iterator, size_type, param_value_type)
+ rinsert(iterator, size_type, value_type)\endlink</code>,
+ <code>rinsert(iterator, InputIterator, InputIterator)</code>,
+ <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
+ <code>\link insert(iterator, size_type, param_value_type)
+ insert(iterator, size_type, value_type)\endlink</code>,
+ <code>insert(iterator, InputIterator, InputIterator)</code>
+ */
+ iterator rinsert(iterator pos) {
+ size_type index = pos - begin();
+ check_low_capacity();
+ return circular_buffer<T, Alloc>::rinsert(begin() + index);
+ }
+
//! Insert <code>n</code> copies of the <code>item</code> before the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
@@ -999,8 +1289,8 @@ public:
\param item The element whose copies will be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1012,7 +1302,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br>
- <code>p ---^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
+ <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
<code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
<code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
@@ -1048,8 +1338,8 @@ public:
\param last The end of the range to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::T(const T&)</code> throws.
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::T(const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1064,7 +1354,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br>
- <code>p ---^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
+ <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
<code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
@@ -1094,7 +1384,8 @@ public:
element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws or
+ nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1124,7 +1415,8 @@ public:
element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws or
+ nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1153,7 +1445,8 @@ public:
such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws or
+ nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1162,7 +1455,7 @@ public:
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
- only for consistency with the base <code><a href="circular_buffer.html">circular_buffer</a></code>.
+ only for consistency with the base <code>circular_buffer</code>.
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
<code>rerase(iterator, iterator)</code>, <code>clear()</code>
*/
@@ -1185,7 +1478,8 @@ public:
such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
- \throws Whatever <code>T::operator = (const T&)</code> throws.
+ Whatever <code>T::operator = (const T&)</code> throws or
+ nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
@@ -1195,7 +1489,7 @@ public:
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
implemented only for consistency with the base
- <code><a href="circular_buffer.html">circular_buffer</a></code>.
+ <code><circular_buffer</code>.
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
<code>clear()</code>
*/
@@ -1300,7 +1594,7 @@ private:
//! Specialized method for determining the initial capacity.
template <class IntegralType>
- static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType item,
+ static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType,
const true_type&) {
return init_capacity(capacity_ctrl, static_cast<size_type>(n));
}
@@ -1311,16 +1605,16 @@ private:
const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
- return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
+ return init_capacity(capacity_ctrl, first, last, iterator_category<Iterator>::type());
#else
return init_capacity(
- capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
+ capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
#endif
}
//! Specialized method for determining the initial capacity.
template <class InputIterator>
- static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator first, InputIterator last,
+ static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator,
const std::input_iterator_tag&) {
return capacity_ctrl.capacity();
}
@@ -1414,7 +1708,7 @@ inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
//! Swap the contents of two space optimized circular buffers.
template <class T, class Alloc>
inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
- circular_buffer_space_optimized<T, Alloc>& rhs) {
+ circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
lhs.swap(rhs);
}