diff options
Diffstat (limited to 'boost/circular_buffer/space_optimized.hpp')
-rw-r--r-- | boost/circular_buffer/space_optimized.hpp | 520 |
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); } |