Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:50

0001 // Implementation of the circular buffer adaptor.
0002 
0003 // Copyright (c) 2003-2008 Jan Gaspar
0004 // Copyright (c) 2013  Paul A. Bristow // Doxygen comments changed for new version of documentation.
0005 // Copyright (c) 2013  Antony Polukhin // Move semantics implementation.
0006 
0007 // Use, modification, and distribution is subject to the Boost Software
0008 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
0012 #define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
0013 
0014 #if defined(_MSC_VER)
0015     #pragma once
0016 #endif
0017 
0018 #include <boost/type_traits/is_same.hpp>
0019 #include <boost/config/workaround.hpp>
0020 
0021 namespace boost {
0022 
0023 /*!
0024     \class circular_buffer_space_optimized
0025     \brief Space optimized circular buffer container adaptor. 
0026            <code>T</code> must be a copyable class or must have an noexcept move constructor
0027            and move assignment operator.
0028 */
0029 template <class T, class Alloc>
0030 class circular_buffer_space_optimized :
0031 /*! \cond */
0032 #if BOOST_CB_ENABLE_DEBUG
0033 public
0034 #endif
0035 /*! \endcond */
0036 circular_buffer<T, Alloc> {
0037 public:
0038 // Typedefs
0039 
0040     typedef typename circular_buffer<T, Alloc>::value_type value_type;
0041     typedef typename circular_buffer<T, Alloc>::pointer pointer;
0042     typedef typename circular_buffer<T, Alloc>::const_pointer const_pointer;
0043     typedef typename circular_buffer<T, Alloc>::reference reference;
0044     typedef typename circular_buffer<T, Alloc>::const_reference const_reference;
0045     typedef typename circular_buffer<T, Alloc>::size_type size_type;
0046     typedef typename circular_buffer<T, Alloc>::difference_type difference_type;
0047     typedef typename circular_buffer<T, Alloc>::allocator_type allocator_type;
0048     typedef typename circular_buffer<T, Alloc>::const_iterator const_iterator;
0049     typedef typename circular_buffer<T, Alloc>::iterator iterator;
0050     typedef typename circular_buffer<T, Alloc>::const_reverse_iterator const_reverse_iterator;
0051     typedef typename circular_buffer<T, Alloc>::reverse_iterator reverse_iterator;
0052     typedef typename circular_buffer<T, Alloc>::array_range array_range;
0053     typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range;
0054     typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type;
0055     typedef typename circular_buffer<T, Alloc>::rvalue_type rvalue_type;
0056     //typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
0057 
0058 /* <pre> is not passed through to html or pdf. So <br> is used in code section below.  Ugly :-(
0059 Ideally want a link to capacity_control, but this would require include details
0060 and this would expose all the functions in details.
0061 There must be a better way of doing this.
0062 */
0063 
0064     /*! Capacity controller of the space optimized circular buffer.
0065 
0066     \see capacity_control in details.hpp.
0067 <p>
0068 <code>
0069 class capacity_control<br>
0070 {<br>
0071    size_type m_capacity;  // Available capacity.<br>
0072    size_type m_min_capacity; // Minimum capacity.<br>
0073 public:<br>
0074    capacity_control(size_type capacity, size_type min_capacity = 0)<br>
0075    : m_capacity(capacity), m_min_capacity(min_capacity)<br>
0076      {};<br>
0077    size_type %capacity() const { return m_capacity; }<br>
0078    size_type min_capacity() const { return m_min_capacity; }<br>
0079    operator size_type() const { return m_capacity; }<br>
0080 };<br>
0081 </code>
0082 </p>
0083 
0084 
0085   <p>Always
0086     <code>capacity >= min_capacity</code>.
0087   </p>
0088   <p>
0089     The <code>capacity()</code> represents the capacity
0090     of the <code>circular_buffer_space_optimized</code> and
0091     the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.
0092  </p>
0093  <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
0094   <code>size_type</code>-like types which ensures compatibility of creating an instance of the
0095   <code>circular_buffer_space_optimized</code> with other STL containers.
0096 
0097   On the other hand the operator <code>%size_type()</code>
0098   provides implicit conversion to the <code>size_type</code> which allows to treat the
0099   capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
0100   <code>circular_buffer</a></code>.
0101 </p>
0102     */
0103     typedef cb_details::capacity_control<size_type> capacity_type;
0104 
0105 // Inherited
0106 
0107     using circular_buffer<T, Alloc>::get_allocator;
0108     using circular_buffer<T, Alloc>::begin;
0109     using circular_buffer<T, Alloc>::end;
0110     using circular_buffer<T, Alloc>::rbegin;
0111     using circular_buffer<T, Alloc>::rend;
0112     using circular_buffer<T, Alloc>::at;
0113     using circular_buffer<T, Alloc>::front;
0114     using circular_buffer<T, Alloc>::back;
0115     using circular_buffer<T, Alloc>::array_one;
0116     using circular_buffer<T, Alloc>::array_two;
0117     using circular_buffer<T, Alloc>::linearize;
0118     using circular_buffer<T, Alloc>::is_linearized;
0119     using circular_buffer<T, Alloc>::rotate;
0120     using circular_buffer<T, Alloc>::size;
0121     using circular_buffer<T, Alloc>::max_size;
0122     using circular_buffer<T, Alloc>::empty;
0123 
0124 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0125     reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); }
0126     const_reference operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
0127 #else
0128     using circular_buffer<T, Alloc>::operator[];
0129 #endif
0130 
0131 private:
0132 // Member variables
0133 
0134     //! The capacity controller of the space optimized circular buffer.
0135     capacity_type m_capacity_ctrl;
0136 
0137 public:
0138 // Overridden
0139 
0140     //! Is the <code>circular_buffer_space_optimized</code> full?
0141     /*!
0142         \return <code>true</code> if the number of elements stored in the <code>circular_buffer_space_optimized</code>
0143                 equals the capacity of the <code>circular_buffer_space_optimized</code>; <code>false</code> otherwise.
0144         \throws Nothing.
0145         \par Exception Safety
0146              No-throw.
0147         \par Iterator Invalidation
0148              Does not invalidate any iterators.
0149         \par Complexity
0150              Constant (in the size of the <code>circular_buffer_space_optimized</code>).
0151         \sa <code>empty()</code>
0152     */
0153     bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); }
0154 
0155     /*! \brief Get the maximum number of elements which can be inserted into the
0156                <code>circular_buffer_space_optimized</code> without overwriting any of already stored elements.
0157         \return <code>capacity().%capacity() - size()</code>
0158         \throws Nothing.
0159         \par Exception Safety
0160              No-throw.
0161         \par Iterator Invalidation
0162              Does not invalidate any iterators.
0163         \par Complexity
0164              Constant (in the size of the <code>circular_buffer_space_optimized</code>).
0165         \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
0166     */
0167     size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); }
0168 
0169     //! Get the capacity of the <code>circular_buffer_space_optimized</code>.
0170     /*!
0171         \return The capacity controller representing the maximum number of elements which can be stored in the
0172                 <code>circular_buffer_space_optimized</code> and the minimal allocated size of the internal buffer.
0173         \throws Nothing.
0174         \par Exception Safety
0175              No-throw.
0176         \par Iterator Invalidation
0177              Does not invalidate any iterators.
0178         \par Complexity
0179              Constant (in the size of the <code>circular_buffer_space_optimized</code>).
0180         \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
0181             <code>set_capacity(const capacity_type&)</code>
0182     */
0183     const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; }
0184 
0185 #if defined(BOOST_CB_TEST)
0186 
0187     // Return the current capacity of the adapted circular buffer.
0188     /*
0189        \note This method is not intended to be used directly by the user.
0190              It is defined only for testing purposes.
0191     */
0192     size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer<T, Alloc>::capacity(); }
0193 
0194 #endif // #if defined(BOOST_CB_TEST)
0195 
0196     /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
0197                <code>circular_buffer_space_optimized</code>.
0198         \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl.capacity()</code><br><br>
0199               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
0200               than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code> <b>last</b>
0201               elements will be removed and the new size will be equal to <code>capacity_ctrl.capacity()</code>.<br><br>
0202               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
0203               than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
0204               necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
0205         \param capacity_ctrl The new capacity controller.
0206         \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
0207                 used).
0208                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0209         \par Exception Safety
0210              Strong.
0211         \par Iterator Invalidation
0212              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0213              equal to <code>end()</code>).
0214         \par Complexity
0215              Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
0216         \note To explicitly clear the extra allocated memory use the <b>shrink-to-fit</b> technique:<br><br>
0217               <code>%boost::%circular_buffer_space_optimized\<int\> cb(1000);<br>
0218               ...<br>
0219               %boost::%circular_buffer_space_optimized\<int\>(cb).swap(cb);</code><br><br>
0220               For more information about the shrink-to-fit technique in STL see
0221               <a href="http://www.gotw.ca/gotw/054.htm">http://www.gotw.ca/gotw/054.htm</a>.
0222         \sa <code>rset_capacity(const capacity_type&)</code>,
0223             <code>\link resize() resize(size_type, const_reference)\endlink</code>
0224     */
0225     void set_capacity(const capacity_type& capacity_ctrl) {
0226         m_capacity_ctrl = capacity_ctrl;
0227         if (capacity_ctrl < size()) {
0228             iterator e = end();
0229             circular_buffer<T, Alloc>::erase(e - (size() - capacity_ctrl), e);
0230         }
0231         adjust_min_capacity();
0232     }
0233 
0234     //! Change the size of the <code>circular_buffer_space_optimized</code>.
0235     /*!
0236         \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
0237               If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
0238               <b>back</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
0239               size. In the case the resulting size exceeds the current capacity the capacity will be set to
0240               <code>new_size</code>.<br><br>
0241               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
0242               than the desired new size then number of <code>[size() - new_size]</code> <b>last</b> elements will be
0243               removed. (The capacity will remain unchanged.)<br><br>
0244               The amount of allocated memory in the internal buffer may be accommodated as necessary.
0245         \param new_size The new size.
0246         \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
0247                     the requested size. (See the <i>Effect</i>.)
0248         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0249                 used).
0250                 Whatever <code>T::T(const T&)</code> throws.
0251         \par Exception Safety
0252              Basic.
0253         \par Iterator Invalidation
0254              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0255              equal to <code>end()</code>).
0256         \par Complexity
0257              Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
0258         \sa <code>\link rresize() rresize(size_type, const_reference)\endlink</code>,
0259             <code>set_capacity(const capacity_type&)</code>
0260     */
0261     void resize(size_type new_size, param_value_type item = value_type()) {
0262         if (new_size > size()) {
0263             if (new_size > m_capacity_ctrl)
0264                 m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
0265             insert(end(), new_size - size(), item);
0266         } else {
0267             iterator e = end();
0268             erase(e - (size() - new_size), e);
0269         }
0270     }
0271 
0272     /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
0273                <code>circular_buffer_space_optimized</code>.
0274         \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl</code><br><br>
0275               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
0276               than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code>
0277               <b>first</b> elements will be removed and the new size will be equal to
0278               <code>capacity_ctrl.capacity()</code>.<br><br>
0279               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
0280               than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
0281               necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
0282         \param capacity_ctrl The new capacity controller.
0283         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0284                 used).
0285                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0286         \par Exception Safety
0287              Strong.
0288         \par Iterator Invalidation
0289              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0290              equal to <code>end()</code>).
0291         \par Complexity
0292              Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
0293         \sa <code>set_capacity(const capacity_type&)</code>,
0294             <code>\link rresize() rresize(size_type, const_reference)\endlink</code>
0295     */
0296     void rset_capacity(const capacity_type& capacity_ctrl) {
0297         m_capacity_ctrl = capacity_ctrl;
0298         if (capacity_ctrl < size()) {
0299             iterator b = begin();
0300             circular_buffer<T, Alloc>::rerase(b, b + (size() - capacity_ctrl));
0301         }
0302         adjust_min_capacity();
0303     }
0304 
0305     //! Change the size of the <code>circular_buffer_space_optimized</code>.
0306     /*!
0307         \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
0308               If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
0309               <b>front</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
0310               size. In the case the resulting size exceeds the current capacity the capacity will be set to
0311               <code>new_size</code>.<br><br>
0312               If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
0313               than the desired new size then number of <code>[size() - new_size]</code> <b>first</b> elements will be
0314               removed. (The capacity will remain unchanged.)<br><br>
0315               The amount of allocated memory in the internal buffer may be accommodated as necessary.
0316         \param new_size The new size.
0317         \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
0318                     the requested size. (See the <i>Effect</i>.)
0319         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0320                 used).
0321                 Whatever <code>T::T(const T&)</code> throws.
0322         \par Exception Safety
0323              Basic.
0324         \par Iterator Invalidation
0325              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0326              equal to <code>end()</code>).
0327         \par Complexity
0328              Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
0329         \sa <code>\link resize() resize(size_type, const_reference)\endlink</code>,
0330             <code>rset_capacity(const capacity_type&)</code>
0331     */
0332     void rresize(size_type new_size, param_value_type item = value_type()) {
0333         if (new_size > size()) {
0334             if (new_size > m_capacity_ctrl)
0335                 m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
0336             rinsert(begin(), new_size - size(), item);
0337         } else {
0338             rerase(begin(), end() - new_size);
0339         }
0340     }
0341 
0342     //! Create an empty space optimized circular buffer with zero capacity.
0343     /*!
0344         \post <code>capacity().%capacity() == 0 \&\& capacity().min_capacity() == 0 \&\& size() == 0</code>
0345         \param alloc The allocator.
0346         \throws Nothing.
0347         \par Complexity
0348              Constant.
0349         \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space
0350                  optimized circular buffer with zero capacity.
0351     */
0352     explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
0353     : circular_buffer<T, Alloc>(0, alloc)
0354     , m_capacity_ctrl(0) {}
0355 
0356     //! Create an empty space optimized circular buffer with the specified capacity.
0357     /*!
0358         \post <code>capacity() == capacity_ctrl \&\& size() == 0</code><br><br>
0359               The amount of allocated memory in the internal buffer is <code>capacity_ctrl.min_capacity()</code>.
0360         \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
0361                              the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
0362                              internal buffer.
0363         \param alloc The allocator.
0364         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0365                 used).
0366         \par Complexity
0367              Constant.
0368     */
0369     explicit circular_buffer_space_optimized(capacity_type capacity_ctrl,
0370         const allocator_type& alloc = allocator_type())
0371     : circular_buffer<T, Alloc>(capacity_ctrl.min_capacity(), alloc)
0372     , m_capacity_ctrl(capacity_ctrl) {}
0373 
0374     /*! \brief Create a full space optimized circular buffer with the specified capacity filled with
0375                <code>capacity_ctrl.%capacity()</code> copies of <code>item</code>.
0376         \post <code>capacity() == capacity_ctrl \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ...
0377               \&\& (*this) [capacity_ctrl.%capacity() - 1] == item </code><br><br>
0378               The amount of allocated memory in the internal buffer is <code>capacity_ctrl.capacity()</code>.
0379         \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
0380                              the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
0381                              internal buffer.
0382         \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
0383         \param alloc The allocator.
0384         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0385                 used).
0386         \throws Whatever <code>T::T(const T&)</code> throws.
0387         \par Complexity
0388              Linear (in the <code>capacity_ctrl.%capacity()</code>).
0389     */
0390     circular_buffer_space_optimized(capacity_type capacity_ctrl, param_value_type item,
0391         const allocator_type& alloc = allocator_type())
0392     : circular_buffer<T, Alloc>(capacity_ctrl.capacity(), item, alloc)
0393     , m_capacity_ctrl(capacity_ctrl) {}
0394 
0395     /*! \brief Create a space optimized circular buffer with the specified capacity filled with <code>n</code> copies
0396                of <code>item</code>.
0397         \pre <code>capacity_ctrl.%capacity() >= n</code>
0398         \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
0399               \&\& ... \&\& (*this)[n - 1] == item</code><br><br>
0400               The amount of allocated memory in the internal buffer is
0401               <code>max[n, capacity_ctrl.min_capacity()]</code>.
0402         \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
0403                              the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
0404                              internal buffer.
0405         \param n The number of elements the created <code>circular_buffer_space_optimized</code> will be filled with.
0406         \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
0407         \param alloc The allocator.
0408         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0409                 used).
0410                 Whatever <code>T::T(const T&)</code> throws.
0411         \par Complexity
0412              Linear (in the <code>n</code>).
0413     */
0414     circular_buffer_space_optimized(capacity_type capacity_ctrl, size_type n, param_value_type item,
0415         const allocator_type& alloc = allocator_type())
0416     : circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
0417     , m_capacity_ctrl(capacity_ctrl) {}
0418 
0419     //! The copy constructor.
0420     /*!
0421         Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
0422         \post <code>*this == cb</code><br><br>
0423               The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
0424         \param cb The <code>circular_buffer_space_optimized</code> to be copied.
0425         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0426                 used).
0427                 Whatever <code>T::T(const T&)</code> throws.
0428         \par Complexity
0429              Linear (in the size of <code>cb</code>).
0430     */
0431     circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
0432     : circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
0433     , m_capacity_ctrl(cb.m_capacity_ctrl) {}
0434 
0435 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0436     //! The move constructor.
0437     /*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>, 
0438                 leaving <code>cb</code> empty.
0439         \pre C++ compiler with rvalue references support.
0440         \post <code>cb.empty()</code>
0441         \param cb <code>circular_buffer</code> to 'steal' value from.
0442         \throws Nothing.
0443         \par Constant.
0444     */
0445     circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
0446     : circular_buffer<T, Alloc>()
0447     , m_capacity_ctrl(0) {
0448         cb.swap(*this);
0449     }
0450 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
0451 
0452     //! Create a full space optimized circular buffer filled with a copy of the range.
0453     /*!
0454         \pre Valid range <code>[first, last)</code>.<br>
0455              <code>first</code> and <code>last</code> have to meet the requirements of
0456              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
0457         \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
0458               full() \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\&
0459               (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
0460               The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
0461         \param first The beginning of the range to be copied.
0462         \param last The end of the range to be copied.
0463         \param alloc The allocator.
0464         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0465                 used).
0466                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept 
0467                 and <code>InputIterator</code> is a move iterator.
0468         \par Complexity
0469              Linear (in the <code>std::distance(first, last)</code>).
0470     */
0471     template <class InputIterator>
0472     circular_buffer_space_optimized(InputIterator first, InputIterator last,
0473         const allocator_type& alloc = allocator_type())
0474     : circular_buffer<T, Alloc>(first, last, alloc)
0475     , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
0476 
0477     /*! \brief Create a space optimized circular buffer with the specified capacity (and the minimal guaranteed amount
0478                of allocated memory) filled with a copy of the range.
0479         \pre Valid range <code>[first, last)</code>.<br>
0480              <code>first</code> and <code>last</code> have to meet the requirements of
0481              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
0482         \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& (*this)[0]==
0483               *(last - capacity_ctrl.%capacity()) \&\& (*this)[1] == *(last - capacity_ctrl.%capacity() + 1) \&\& ...
0484               \&\& (*this)[capacity_ctrl.%capacity() - 1] == *(last - 1)</code><br><br>
0485               If the number of items to be copied from the range <code>[first, last)</code> is greater than the
0486               specified <code>capacity_ctrl.%capacity()</code> then only elements from the range
0487               <code>[last - capacity_ctrl.%capacity(), last)</code> will be copied.<br><br>
0488               The amount of allocated memory in the internal buffer is <code>max[capacity_ctrl.min_capacity(),
0489               min[capacity_ctrl.%capacity(), std::distance(first, last)]]</code>.
0490         \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
0491                              the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
0492                              internal buffer.
0493         \param first The beginning of the range to be copied.
0494         \param last The end of the range to be copied.
0495         \param alloc The allocator.
0496         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0497                 used).
0498                 Whatever <code>T::T(const T&)</code> throws.
0499         \par Complexity
0500              Linear (in <code>std::distance(first, last)</code>; in
0501              <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
0502              is a <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
0503     */
0504     template <class InputIterator>
0505     circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last,
0506         const allocator_type& alloc = allocator_type())
0507     : circular_buffer<T, Alloc>(
0508         init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
0509         first, last, alloc)
0510     , m_capacity_ctrl(capacity_ctrl) {
0511         reduce_capacity(
0512             is_same< BOOST_DEDUCED_TYPENAME std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag >());
0513     }
0514 
0515 #if defined(BOOST_CB_NEVER_DEFINED)
0516 // This section will never be compiled - the default destructor will be generated instead.
0517 // Declared only for documentation purpose.
0518 
0519     //! The destructor.
0520     /*!
0521         Destroys the <code>circular_buffer_space_optimized</code>.
0522         \throws Nothing.
0523         \par Iterator Invalidation
0524              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (including
0525              iterators equal to <code>end()</code>).
0526         \par Complexity
0527              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0528         \sa <code>clear()</code>
0529     */
0530     ~circular_buffer_space_optimized();
0531 
0532     //! no-comment
0533     void erase_begin(size_type n);
0534 
0535     //! no-comment
0536     void erase_end(size_type n);
0537 
0538 #endif // #if defined(BOOST_CB_NEVER_DEFINED)
0539 
0540     //! The assign operator.
0541     /*!
0542         Makes this <code>circular_buffer_space_optimized</code> to become a copy of the specified
0543         <code>circular_buffer_space_optimized</code>.
0544         \post <code>*this == cb</code><br><br>
0545               The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
0546         \param cb The <code>circular_buffer_space_optimized</code> to be copied.
0547         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0548                 used).
0549         \throws Whatever <code>T::T(const T&)</code> throws.
0550         \par Exception Safety
0551              Strong.
0552         \par Iterator Invalidation
0553              Invalidates all iterators pointing to this <code>circular_buffer_space_optimized</code> (except iterators
0554              equal to <code>end()</code>).
0555         \par Complexity
0556              Linear (in the size of <code>cb</code>).
0557         \sa <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
0558             <code>\link assign(capacity_type, size_type, param_value_type)
0559             assign(capacity_type, size_type, const_reference)\endlink</code>,
0560             <code>assign(InputIterator, InputIterator)</code>,
0561             <code>assign(capacity_type, InputIterator, InputIterator)</code>
0562     */
0563     circular_buffer_space_optimized<T, Alloc>& operator = (const circular_buffer_space_optimized<T, Alloc>& cb) {
0564         if (this == &cb)
0565             return *this;
0566         circular_buffer<T, Alloc>::assign(cb.begin(), cb.end());
0567         m_capacity_ctrl = cb.m_capacity_ctrl;
0568         return *this;
0569     }
0570 
0571 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0572     /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
0573         \pre C++ compiler with rvalue references support.
0574         \post <code>cb.empty()</code>
0575         \param cb <code>circular_buffer</code> to 'steal' value from.
0576         \throws Nothing.
0577         \par Complexity
0578              Constant.
0579     */
0580     circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
0581         cb.swap(*this); // now `this` holds `cb`
0582         circular_buffer<T, Alloc>(get_allocator()) // temporary that holds initial `cb` allocator
0583             .swap(cb); // makes `cb` empty
0584         return *this;
0585     }
0586 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
0587 
0588 
0589     //! Assign <code>n</code> items into the space optimized circular buffer.
0590     /*!
0591         The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
0592         <code>n</code> copies of the <code>item</code>.
0593         \post <code>capacity().%capacity() == n \&\& capacity().min_capacity() == 0 \&\& size() == n \&\& (*this)[0] ==
0594               item \&\& (*this)[1] == item \&\& ... \&\& (*this) [n - 1] == item</code><br><br>
0595               The amount of allocated memory in the internal buffer is <code>n</code>.
0596         \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
0597         \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
0598         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0599                 used).
0600                 Whatever <code>T::T(const T&)</code> throws.
0601         \par Exception Safety
0602              Basic.
0603         \par Iterator Invalidation
0604              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0605              equal to <code>end()</code>).
0606         \par Complexity
0607              Linear (in the <code>n</code>).
0608         \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
0609             <code>\link assign(capacity_type, size_type, param_value_type)
0610             assign(capacity_type, size_type, const_reference)\endlink</code>,
0611             <code>assign(InputIterator, InputIterator)</code>,
0612             <code>assign(capacity_type, InputIterator, InputIterator)</code>
0613     */
0614     void assign(size_type n, param_value_type item) {
0615         circular_buffer<T, Alloc>::assign(n, item);
0616         m_capacity_ctrl = capacity_type(n);
0617     }
0618 
0619     //! Assign <code>n</code> items into the space optimized circular buffer specifying the capacity.
0620     /*!
0621         The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
0622         content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with <code>n</code>
0623         copies of the <code>item</code>.
0624         \pre <code>capacity_ctrl.%capacity() >= n</code>
0625         \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
0626               \&\& ... \&\& (*this) [n - 1] == item </code><br><br>
0627               The amount of allocated memory will be <code>max[n, capacity_ctrl.min_capacity()]</code>.
0628         \param capacity_ctrl The new capacity controller.
0629         \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
0630         \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
0631         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0632                 used).
0633                 Whatever <code>T::T(const T&)</code> throws.
0634         \par Exception Safety
0635              Basic.
0636         \par Iterator Invalidation
0637              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0638              equal to <code>end()</code>).
0639         \par Complexity
0640              Linear (in the <code>n</code>).
0641         \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
0642             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
0643             <code>assign(InputIterator, InputIterator)</code>,
0644             <code>assign(capacity_type, InputIterator, InputIterator)</code>
0645     */
0646     void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) {
0647        BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for new capacity lower than n
0648        circular_buffer<T, Alloc>::assign((std::max)(capacity_ctrl.min_capacity(), n), n, item);
0649        m_capacity_ctrl = capacity_ctrl;
0650     }
0651 
0652     //! Assign a copy of the range into the space optimized circular buffer.
0653     /*!
0654         The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
0655         elements from the specified range.
0656         \pre Valid range <code>[first, last)</code>.<br>
0657              <code>first</code> and <code>last</code> have to meet the requirements of
0658              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
0659         \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
0660               size() == std::distance(first, last) \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ...
0661               \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
0662               The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
0663         \param first The beginning of the range to be copied.
0664         \param last The end of the range to be copied.
0665         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0666                 used).
0667                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and 
0668                 <code>InputIterator</code> is a move iterator.
0669         \par Exception Safety
0670              Basic.
0671         \par Iterator Invalidation
0672              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0673              equal to <code>end()</code>).
0674         \par Complexity
0675              Linear (in the <code>std::distance(first, last)</code>).
0676         \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
0677             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
0678             <code>\link assign(capacity_type, size_type, param_value_type)
0679             assign(capacity_type, size_type, const_reference)\endlink</code>,
0680             <code>assign(capacity_type, InputIterator, InputIterator)</code>
0681     */
0682     template <class InputIterator>
0683     void assign(InputIterator first, InputIterator last) {
0684         circular_buffer<T, Alloc>::assign(first, last);
0685         m_capacity_ctrl = capacity_type(circular_buffer<T, Alloc>::capacity());
0686     }
0687 
0688     //! Assign a copy of the range into the space optimized circular buffer specifying the capacity.
0689     /*!
0690         The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
0691         content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
0692         elements from the specified range.
0693         \pre Valid range <code>[first, last)</code>.<br>
0694              <code>first</code> and <code>last</code> have to meet the requirements of
0695              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
0696         \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\&
0697              (*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
0698              (*this)[capacity - 1] == *(last - 1)</code><br><br>
0699              If the number of items to be copied from the range <code>[first, last)</code> is greater than the
0700              specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
0701              will be copied.<br><br> The amount of allocated memory in the internal buffer is
0702              <code>max[std::distance(first, last), capacity_ctrl.min_capacity()]</code>.
0703         \param capacity_ctrl The new capacity controller.
0704         \param first The beginning of the range to be copied.
0705         \param last The end of the range to be copied.
0706         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0707                 used).
0708                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and 
0709                 <code>InputIterator</code> is a move iterator.
0710         \par Exception Safety
0711              Basic.
0712         \par Iterator Invalidation
0713              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0714              equal to <code>end()</code>).
0715         \par Complexity
0716              Linear (in <code>std::distance(first, last)</code>; in
0717              <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
0718              is a <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
0719         \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
0720             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
0721             <code>\link assign(capacity_type, size_type, param_value_type)
0722             assign(capacity_type, size_type, const_reference)\endlink</code>,
0723             <code>assign(InputIterator, InputIterator)</code>
0724     */
0725     template <class InputIterator>
0726     void assign(capacity_type capacity_ctrl, InputIterator first, InputIterator last) {
0727        m_capacity_ctrl = capacity_ctrl;
0728        circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
0729     }
0730 
0731     //! Swap the contents of two space-optimized circular-buffers.
0732     /*!
0733         \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
0734               allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
0735               allocated memory of <code>cb</code> and vice versa.
0736         \param cb The <code>circular_buffer_space_optimized</code> whose content will be swapped.
0737         \throws Nothing.
0738         \par Exception Safety
0739              No-throw.
0740         \par Iterator Invalidation
0741              Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
0742              hand the iterators still point to the same elements but within another container. If you want to rely on
0743              this feature you have to turn the __debug_support off,
0744              otherwise an assertion will report an error if such invalidated iterator is used.)
0745         \par Complexity
0746              Constant (in the size of the <code>circular_buffer_space_optimized</code>).
0747         \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>, 
0748             <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
0749 
0750 
0751     */
0752     // Note link does not work right.  Asked on Doxygen forum for advice 23 May 2103.
0753 
0754     void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
0755         std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
0756         circular_buffer<T, Alloc>::swap(cb);
0757     }
0758 
0759     //! Insert a new element at the end of the space optimized circular buffer.
0760     /*!
0761         \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
0762               If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
0763               capacity is <code>0</code>, nothing will be inserted.<br><br>
0764               The amount of allocated memory in the internal buffer may be predictively increased.
0765         \param item The element to be inserted.
0766         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0767                 used).
0768                 Whatever <code>T::T(const T&)</code> throws.
0769         \par Exception Safety
0770              Basic.
0771         \par Iterator Invalidation
0772              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0773              equal to <code>end()</code>).
0774         \par Complexity
0775              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0776         \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
0777             <code>pop_front()</code>
0778     */
0779     void push_back(param_value_type item) {
0780         check_low_capacity();
0781         circular_buffer<T, Alloc>::push_back(item);
0782     }
0783 
0784     //! Insert a new element at the end of the space optimized circular buffer.
0785     /*!
0786         \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
0787               If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
0788               capacity is <code>0</code>, nothing will be inserted.<br><br>
0789               The amount of allocated memory in the internal buffer may be predictively increased.
0790         \param item The element to be inserted.
0791         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0792                 used).
0793         \par Exception Safety
0794              Basic.
0795         \par Iterator Invalidation
0796              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0797              equal to <code>end()</code>).
0798         \par Complexity
0799              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0800         \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
0801             <code>pop_front()</code>
0802     */
0803     void push_back(rvalue_type item) {
0804         check_low_capacity();
0805         circular_buffer<T, Alloc>::push_back(boost::move(item));
0806     }
0807 
0808     //! Insert a new element at the end of the space optimized circular buffer.
0809     /*!
0810         \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
0811               If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
0812               capacity is <code>0</code>, nothing will be inserted.<br><br>
0813               The amount of allocated memory in the internal buffer may be predictively increased.
0814         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0815                 used).
0816                 Whatever <code>T::T()</code> throws. 
0817                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0818         \par Exception Safety
0819              Basic.
0820         \par Iterator Invalidation
0821              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0822              equal to <code>end()</code>).
0823         \par Complexity
0824              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0825         \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
0826             <code>pop_front()</code>
0827     */
0828     void push_back() {
0829         check_low_capacity();
0830         circular_buffer<T, Alloc>::push_back();
0831     }
0832 
0833     //! Insert a new element at the beginning of the space optimized circular buffer.
0834     /*!
0835         \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
0836               If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
0837               capacity is <code>0</code>, nothing will be inserted.<br><br>
0838               The amount of allocated memory in the internal buffer may be predictively increased.
0839         \param item The element to be inserted.
0840         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0841                 used).
0842                 Whatever <code>T::T(const T&)</code> throws.
0843         \par Exception Safety
0844              Basic.
0845         \par Iterator Invalidation
0846              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0847              equal to <code>end()</code>).
0848         \par Complexity
0849              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0850         \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
0851             <code>pop_front()</code>
0852     */
0853     void push_front(param_value_type item) {
0854         check_low_capacity();
0855         circular_buffer<T, Alloc>::push_front(item);
0856     }
0857 
0858     //! Insert a new element at the beginning of the space optimized circular buffer.
0859     /*!
0860         \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
0861               If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
0862               capacity is <code>0</code>, nothing will be inserted.<br><br>
0863               The amount of allocated memory in the internal buffer may be predictively increased.
0864         \param item The element to be inserted.
0865         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0866                 used).
0867                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0868         \par Exception Safety
0869              Basic.
0870         \par Iterator Invalidation
0871              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0872              equal to <code>end()</code>).
0873         \par Complexity
0874              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0875         \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
0876             <code>pop_front()</code>
0877     */
0878     void push_front(rvalue_type item) {
0879         check_low_capacity();
0880         circular_buffer<T, Alloc>::push_front(boost::move(item));
0881     }
0882 
0883     //! Insert a new element at the beginning of the space optimized circular buffer.
0884     /*!
0885         \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
0886               If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
0887               capacity is <code>0</code>, nothing will be inserted.<br><br>
0888               The amount of allocated memory in the internal buffer may be predictively increased.
0889         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0890                 used).
0891                 Whatever <code>T::T()</code> throws.
0892                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0893         \par Exception Safety
0894              Basic.
0895         \par Iterator Invalidation
0896              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0897              equal to <code>end()</code>).
0898         \par Complexity
0899              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0900         \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
0901             <code>pop_front()</code>
0902     */
0903     void push_front() {
0904         check_low_capacity();
0905         circular_buffer<T, Alloc>::push_front();
0906     }
0907 
0908     //! Remove the last element from the space optimized circular buffer.
0909     /*!
0910         \pre <code>!empty()</code>
0911         \post The last element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
0912               The amount of allocated memory in the internal buffer may be predictively decreased.
0913         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0914                 used).
0915         \par Exception Safety
0916              Basic.
0917         \par Iterator Invalidation
0918              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0919              equal to <code>end()</code>).
0920         \par Complexity
0921              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0922         \sa <code>pop_front()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
0923             <code>\link push_front() push_front(const_reference)\endlink</code>
0924     */
0925     void pop_back() {
0926         circular_buffer<T, Alloc>::pop_back();
0927         check_high_capacity();
0928     }
0929 
0930     //! Remove the first element from the space optimized circular buffer.
0931     /*!
0932         \pre <code>!empty()</code>
0933         \post The first element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
0934               The amount of allocated memory in the internal buffer may be predictively decreased.
0935         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0936                 used).
0937         \par Exception Safety
0938              Basic.
0939         \par Iterator Invalidation
0940              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0941              equal to <code>end()</code>).
0942         \par Complexity
0943              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0944         \sa <code>pop_back()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
0945             <code>\link push_front() push_front(const_reference)\endlink</code>
0946     */
0947     void pop_front() {
0948         circular_buffer<T, Alloc>::pop_front();
0949         check_high_capacity();
0950     }
0951 
0952     //! Insert an element at the specified position.
0953     /*!
0954         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
0955              end.
0956         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
0957               If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
0958               the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
0959               <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
0960               nothing will be inserted.<br><br>
0961               The amount of allocated memory in the internal buffer may be predictively increased.
0962         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
0963         \param item The element to be inserted.
0964         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
0965                 the <i>Effect</i>.)
0966         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0967                 used).
0968                 Whatever <code>T::T(const T&)</code> throws.
0969                 Whatever <code>T::operator = (const T&)</code> throws.
0970         \par Exception Safety
0971              Basic.
0972         \par Iterator Invalidation
0973              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
0974              equal to <code>end()</code>).
0975         \par Complexity
0976              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
0977         \sa <code>\link insert(iterator, size_type, param_value_type)
0978             insert(iterator, size_type, value_type)\endlink</code>,
0979             <code>insert(iterator, InputIterator, InputIterator)</code>,
0980             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
0981             <code>\link rinsert(iterator, size_type, param_value_type)
0982             rinsert(iterator, size_type, value_type)\endlink</code>,
0983             <code>rinsert(iterator, InputIterator, InputIterator)</code>
0984     */
0985     iterator insert(iterator pos, param_value_type item) {
0986         size_type index = pos - begin();
0987         check_low_capacity();
0988         return circular_buffer<T, Alloc>::insert(begin() + index, item);
0989     }
0990 
0991     //! Insert an element at the specified position.
0992     /*!
0993         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
0994              end.
0995         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
0996               If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
0997               the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
0998               <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
0999               nothing will be inserted.<br><br>
1000               The amount of allocated memory in the internal buffer may be predictively increased.
1001         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1002         \param item The element to be inserted.
1003         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1004                 the <i>Effect</i>.)
1005         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1006                 used).
1007                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1008         \par Exception Safety
1009              Basic.
1010         \par Iterator Invalidation
1011              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1012              equal to <code>end()</code>).
1013         \par Complexity
1014              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1015         \sa <code>\link insert(iterator, size_type, param_value_type)
1016             insert(iterator, size_type, value_type)\endlink</code>,
1017             <code>insert(iterator, InputIterator, InputIterator)</code>,
1018             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1019             <code>\link rinsert(iterator, size_type, param_value_type)
1020             rinsert(iterator, size_type, value_type)\endlink</code>,
1021             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1022     */
1023     iterator insert(iterator pos, rvalue_type item) {
1024         size_type index = pos - begin();
1025         check_low_capacity();
1026         return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
1027     }
1028 
1029     //! Insert an element at the specified position.
1030     /*!
1031         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1032              end.
1033         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1034               If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
1035               the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1036               <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1037               nothing will be inserted.<br><br>
1038               The amount of allocated memory in the internal buffer may be predictively increased.
1039         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1040         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1041                 the <i>Effect</i>.)
1042         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1043                 used).
1044                 Whatever <code>T::T()</code> throws.
1045                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1046         \par Exception Safety
1047              Basic.
1048         \par Iterator Invalidation
1049              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1050              equal to <code>end()</code>).
1051         \par Complexity
1052              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1053         \sa <code>\link insert(iterator, size_type, param_value_type)
1054             insert(iterator, size_type, value_type)\endlink</code>,
1055             <code>insert(iterator, InputIterator, InputIterator)</code>,
1056             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1057             <code>\link rinsert(iterator, size_type, param_value_type)
1058             rinsert(iterator, size_type, value_type)\endlink</code>,
1059             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1060     */
1061     iterator insert(iterator pos) {
1062         size_type index = pos - begin();
1063         check_low_capacity();
1064         return circular_buffer<T, Alloc>::insert(begin() + index);
1065     }
1066 
1067     //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
1068     /*!
1069         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1070              end.
1071         \post The number of <code>min[n, (pos - begin()) + reserve()]</code> elements will be inserted at the position
1072               <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0, n - reserve()]]</code> elements will
1073               be overwritten at the beginning of the <code>circular_buffer_space_optimized</code>.<br>(See
1074               <i>Example</i> for the explanation.)<br><br>
1075               The amount of allocated memory in the internal buffer may be predictively increased.
1076         \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
1077         \param n The number of <code>item</code>s the to be inserted.
1078         \param item The element whose copies will be inserted.
1079         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1080                 used).
1081                 Whatever <code>T::T(const T&)</code> throws.
1082                 Whatever <code>T::operator = (const T&)</code> throws.
1083         \par Exception Safety
1084              Basic.
1085         \par Iterator Invalidation
1086              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1087              equal to <code>end()</code>).
1088         \par Complexity
1089              Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
1090         \par Example
1091              Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1092              internal buffer may look like the one below.<br><br>
1093              <code>|1|2|3|4| | |</code><br>
1094              <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
1095              <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
1096              <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
1097              the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
1098              <br>For comparison if the capacity would not be preserved the internal buffer would then result in
1099              <code>|1|2|0|0|0|0|0|3|4|</code>.
1100         \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1101             <code>insert(iterator, InputIterator, InputIterator)</code>,
1102             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1103             <code>\link rinsert(iterator, size_type, param_value_type)
1104             rinsert(iterator, size_type, value_type)\endlink</code>,
1105             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1106     */
1107     void insert(iterator pos, size_type n, param_value_type item) {
1108         size_type index = pos - begin();
1109         check_low_capacity(n);
1110         circular_buffer<T, Alloc>::insert(begin() + index, n, item);
1111     }
1112 
1113     //! Insert the range <code>[first, last)</code> at the specified position.
1114     /*!
1115         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1116              end.<br>Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
1117              requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1118         \post Elements from the range
1119               <code>[first + max[0, distance(first, last) - (pos - begin()) - reserve()], last)</code> will be
1120               inserted at the position <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0,
1121               distance(first, last) - reserve()]]</code> elements will be overwritten at the beginning of the
1122               <code>circular_buffer_space_optimized</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
1123               The amount of allocated memory in the internal buffer may be predictively increased.
1124         \param pos An iterator specifying the position where the range will be inserted.
1125         \param first The beginning of the range to be inserted.
1126         \param last The end of the range to be inserted.
1127         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1128                 used).
1129                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1130         \par Exception Safety
1131              Basic.
1132         \par Iterator Invalidation
1133              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1134              equal to <code>end()</code>).
1135         \par Complexity
1136              Linear (in <code>[size() + std::distance(first, last)]</code>; in
1137              <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
1138              <code>InputIterator</code> is a
1139              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1140         \par Example
1141              Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1142              internal buffer may look like the one below.<br><br>
1143              <code>|1|2|3|4| | |</code><br>
1144              <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
1145              <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
1146              actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
1147              specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
1148              to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like
1149              this:<br><br><code>|6|7|8|9|3|4|</code><br><br>For comparison if the capacity would not be preserved the
1150              internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
1151         \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1152             <code>\link insert(iterator, size_type, param_value_type)
1153             insert(iterator, size_type, value_type)\endlink</code>, <code>\link rinsert(iterator, param_value_type)
1154             rinsert(iterator, value_type)\endlink</code>, <code>\link rinsert(iterator, size_type, param_value_type)
1155             rinsert(iterator, size_type, value_type)\endlink</code>,
1156             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1157     */
1158     template <class InputIterator>
1159     void insert(iterator pos, InputIterator first, InputIterator last) {
1160         insert(pos, first, last, is_integral<InputIterator>());
1161     }
1162 
1163     //! Insert an element before the specified position.
1164     /*!
1165         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1166              end.
1167         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1168               If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1169               <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1170               <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1171               nothing will be inserted.<br><br>
1172               The amount of allocated memory in the internal buffer may be predictively increased.
1173         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1174         \param item The element to be inserted.
1175         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1176                 the <i>Effect</i>.)
1177         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1178                 used).
1179                 Whatever <code>T::T(const T&)</code> throws.
1180                 Whatever <code>T::operator = (const T&)</code> throws.
1181         \par Exception Safety
1182              Basic.
1183         \par Iterator Invalidation
1184              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1185              equal to <code>end()</code>).
1186         \par Complexity
1187              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1188         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1189             rinsert(iterator, size_type, value_type)\endlink</code>,
1190             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1191             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1192             <code>\link insert(iterator, size_type, param_value_type)
1193             insert(iterator, size_type, value_type)\endlink</code>,
1194             <code>insert(iterator, InputIterator, InputIterator)</code>
1195     */
1196     iterator rinsert(iterator pos, param_value_type item) {
1197         size_type index = pos - begin();
1198         check_low_capacity();
1199         return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
1200     }
1201 
1202     //! Insert an element before the specified position.
1203     /*!
1204         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1205              end.
1206         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1207               If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1208               <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1209               <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1210               nothing will be inserted.<br><br>
1211               The amount of allocated memory in the internal buffer may be predictively increased.
1212         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1213         \param item The element to be inserted.
1214         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1215                 the <i>Effect</i>.)
1216         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1217                 used).
1218                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1219         \par Exception Safety
1220              Basic.
1221         \par Iterator Invalidation
1222              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1223              equal to <code>end()</code>).
1224         \par Complexity
1225              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1226         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1227             rinsert(iterator, size_type, value_type)\endlink</code>,
1228             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1229             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1230             <code>\link insert(iterator, size_type, param_value_type)
1231             insert(iterator, size_type, value_type)\endlink</code>,
1232             <code>insert(iterator, InputIterator, InputIterator)</code>
1233     */
1234     iterator rinsert(iterator pos, rvalue_type item) {
1235         size_type index = pos - begin();
1236         check_low_capacity();
1237         return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
1238     }
1239 
1240     //! Insert an element before the specified position.
1241     /*!
1242         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1243              end.
1244         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1245               If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1246               <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1247               <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1248               nothing will be inserted.<br><br>
1249               The amount of allocated memory in the internal buffer may be predictively increased.
1250         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1251         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1252                 the <i>Effect</i>.)
1253         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1254                 used).
1255                 Whatever <code>T::T()</code> throws.
1256                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1257         \par Exception Safety
1258              Basic.
1259         \par Iterator Invalidation
1260              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1261              equal to <code>end()</code>).
1262         \par Complexity
1263              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1264         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1265             rinsert(iterator, size_type, value_type)\endlink</code>,
1266             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1267             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1268             <code>\link insert(iterator, size_type, param_value_type)
1269             insert(iterator, size_type, value_type)\endlink</code>,
1270             <code>insert(iterator, InputIterator, InputIterator)</code>
1271     */
1272     iterator rinsert(iterator pos) {
1273         size_type index = pos - begin();
1274         check_low_capacity();
1275         return circular_buffer<T, Alloc>::rinsert(begin() + index);
1276     }
1277 
1278     //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
1279     /*!
1280         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1281              end.
1282         \post The number of <code>min[n, (end() - pos) + reserve()]</code> elements will be inserted before the
1283               position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0, n - reserve()]]</code> elements
1284               will be overwritten at the end of the <code>circular_buffer_space_optimized</code>.<br>(See
1285               <i>Example</i> for the explanation.)<br><br>
1286               The amount of allocated memory in the internal buffer may be predictively increased.
1287         \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
1288         \param n The number of <code>item</code>s the to be inserted.
1289         \param item The element whose copies will be inserted.
1290         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1291                 used).
1292                 Whatever <code>T::T(const T&)</code> throws.
1293                 Whatever <code>T::operator = (const T&)</code> throws.
1294         \par Exception Safety
1295              Basic.
1296         \par Iterator Invalidation
1297              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1298              equal to <code>end()</code>).
1299         \par Complexity
1300              Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
1301         \par Example
1302              Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1303              internal buffer may look like the one below.<br><br>
1304              <code>|1|2|3|4| | |</code><br>
1305              <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
1306              <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
1307              <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
1308              the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
1309              <br>For comparison if the capacity would not be preserved the internal buffer would then result in
1310              <code>|1|2|0|0|0|0|0|3|4|</code>.
1311         \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1312             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1313             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1314             <code>\link insert(iterator, size_type, param_value_type)
1315             insert(iterator, size_type, value_type)\endlink</code>,
1316             <code>insert(iterator, InputIterator, InputIterator)</code>
1317     */
1318     void rinsert(iterator pos, size_type n, param_value_type item) {
1319         size_type index = pos - begin();
1320         check_low_capacity(n);
1321         circular_buffer<T, Alloc>::rinsert(begin() + index, n, item);
1322     }
1323 
1324         //! Insert the range <code>[first, last)</code> before the specified position.
1325     /*!
1326         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1327              end.<br>
1328              Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
1329              requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1330         \post Elements from the range
1331               <code>[first, last - max[0, distance(first, last) - (end() - pos) - reserve()])</code> will be inserted
1332               before the position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0,
1333               distance(first, last) - reserve()]]</code> elements will be overwritten at the end of the
1334               <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
1335               The amount of allocated memory in the internal buffer may be predictively increased.
1336         \param pos An iterator specifying the position where the range will be inserted.
1337         \param first The beginning of the range to be inserted.
1338         \param last The end of the range to be inserted.
1339         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1340                 used).
1341                 Whatever <code>T::T(const T&)</code> throws.
1342                 Whatever <code>T::operator = (const T&)</code> throws.
1343         \par Exception Safety
1344              Basic.
1345         \par Iterator Invalidation
1346              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1347              equal to <code>end()</code>).
1348         \par Complexity
1349              Linear (in <code>[size() + std::distance(first, last)]</code>; in
1350              <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
1351              <code>InputIterator</code> is a
1352              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1353         \par Example
1354              Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1355              internal buffer may look like the one below.<br><br>
1356              <code>|1|2|3|4| | |</code><br>
1357              <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
1358              <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
1359              actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
1360              specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
1361              to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like
1362              this:<br><br><code>|1|2|5|6|7|8|</code><br><br>For comparison if the capacity would not be preserved the
1363              internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
1364         \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1365             <code>\link rinsert(iterator, size_type, param_value_type)
1366             rinsert(iterator, size_type, value_type)\endlink</code>, <code>\link insert(iterator, param_value_type)
1367             insert(iterator, value_type)\endlink</code>, <code>\link insert(iterator, size_type, param_value_type)
1368             insert(iterator, size_type, value_type)\endlink</code>,
1369             <code>insert(iterator, InputIterator, InputIterator)</code>
1370     */
1371     template <class InputIterator>
1372     void rinsert(iterator pos, InputIterator first, InputIterator last) {
1373         rinsert(pos, first, last, is_integral<InputIterator>());
1374     }
1375 
1376     //! Remove an element at the specified position.
1377     /*!
1378         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
1379              an <code>end()</code>).
1380         \post The element at the position <code>pos</code> is removed.<br><br>
1381               The amount of allocated memory in the internal buffer may be predictively decreased.
1382         \param pos An iterator pointing at the element to be removed.
1383         \return Iterator to the first element remaining beyond the removed element or <code>end()</code> if no such
1384                 element exists.
1385         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1386                 used).
1387                 Whatever <code>T::operator = (const T&)</code> throws or 
1388                 nothing if <code>T::operator = (T&&)</code> is noexcept.
1389         \par Exception Safety
1390              Basic.
1391         \par Iterator Invalidation
1392              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1393              equal to <code>end()</code>).
1394         \par Complexity
1395              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1396         \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1397             <code>rerase(iterator, iterator)</code>, <code>clear()</code>
1398     */
1399     iterator erase(iterator pos) {
1400         iterator it = circular_buffer<T, Alloc>::erase(pos);
1401         size_type index = it - begin();
1402         check_high_capacity();
1403         return begin() + index;
1404     }
1405 
1406     //! Erase the range <code>[first, last)</code>.
1407     /*!
1408         \pre Valid range <code>[first, last)</code>.
1409         \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
1410               nothing is removed.)<br><br>
1411               The amount of allocated memory in the internal buffer may be predictively decreased.
1412         \param first The beginning of the range to be removed.
1413         \param last The end of the range to be removed.
1414         \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such
1415                 element exists.
1416         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1417                 used).
1418                 Whatever <code>T::operator = (const T&)</code> throws or 
1419                 nothing if <code>T::operator = (T&&)</code> is noexcept.
1420         \par Exception Safety
1421              Basic.
1422         \par Iterator Invalidation
1423              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1424              equal to <code>end()</code>).
1425         \par Complexity
1426              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1427         \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
1428             <code>clear()</code>
1429     */
1430     iterator erase(iterator first, iterator last) {
1431         iterator it = circular_buffer<T, Alloc>::erase(first, last);
1432         size_type index = it - begin();
1433         check_high_capacity();
1434         return begin() + index;
1435     }
1436 
1437     //! Remove an element at the specified position.
1438     /*!
1439         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
1440              an <code>end()</code>).<br><br>
1441               The amount of allocated memory in the internal buffer may be predictively decreased.
1442         \post The element at the position <code>pos</code> is removed.
1443         \param pos An iterator pointing at the element to be removed.
1444         \return Iterator to the first element remaining in front of the removed element or <code>begin()</code> if no
1445                 such element exists.
1446         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1447                 used).
1448                 Whatever <code>T::operator = (const T&)</code> throws or 
1449                 nothing if <code>T::operator = (T&&)</code> is noexcept.
1450         \par Exception Safety
1451              Basic.
1452         \par Iterator Invalidation
1453              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1454              equal to <code>end()</code>).
1455         \par Complexity
1456              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1457         \note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
1458               only for consistency with the base <code>circular_buffer</code>.
1459         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
1460             <code>rerase(iterator, iterator)</code>, <code>clear()</code>
1461     */
1462     iterator rerase(iterator pos) {
1463         iterator it = circular_buffer<T, Alloc>::rerase(pos);
1464         size_type index = it - begin();
1465         check_high_capacity();
1466         return begin() + index;
1467     }
1468 
1469     //! Erase the range <code>[first, last)</code>.
1470     /*!
1471         \pre Valid range <code>[first, last)</code>.
1472         \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
1473               nothing is removed.)<br><br>
1474               The amount of allocated memory in the internal buffer may be predictively decreased.
1475         \param first The beginning of the range to be removed.
1476         \param last The end of the range to be removed.
1477         \return Iterator to the first element remaining in front of the removed elements or <code>begin()</code> if no
1478                 such element exists.
1479         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1480                 used).
1481                 Whatever <code>T::operator = (const T&)</code> throws or 
1482                 nothing if <code>T::operator = (T&&)</code> is noexcept.
1483         \par Exception Safety
1484              Basic.
1485         \par Iterator Invalidation
1486              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1487              equal to <code>end()</code>).
1488         \par Complexity
1489              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1490         \note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
1491               implemented only for consistency with the base
1492               <code><circular_buffer</code>.
1493         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1494             <code>clear()</code>
1495     */
1496     iterator rerase(iterator first, iterator last) {
1497         iterator it = circular_buffer<T, Alloc>::rerase(first, last);
1498         size_type index = it - begin();
1499         check_high_capacity();
1500         return begin() + index;
1501     }
1502 
1503     //! Remove all stored elements from the space optimized circular buffer.
1504     /*!
1505         \post <code>size() == 0</code><br><br>
1506               The amount of allocated memory in the internal buffer may be predictively decreased.
1507         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1508                 used).
1509         \par Exception Safety
1510              Basic.
1511         \par Iterator Invalidation
1512              Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1513              equal to <code>end()</code>).
1514         \par Complexity
1515              Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1516         \sa <code>~circular_buffer_space_optimized()</code>, <code>erase(iterator)</code>,
1517             <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1518             <code>rerase(iterator, iterator)</code>
1519     */
1520     void clear() { erase(begin(), end()); }
1521 
1522 private:
1523 // Helper methods
1524 
1525     /*! INTERNAL ONLY */
1526     void adjust_min_capacity() {
1527         if (m_capacity_ctrl.min_capacity() > circular_buffer<T, Alloc>::capacity())
1528             circular_buffer<T, Alloc>::set_capacity(m_capacity_ctrl.min_capacity());
1529         else
1530             check_high_capacity();
1531     }
1532 
1533     /*! INTERNAL ONLY */
1534     size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const {
1535         if (buffer_size + new_capacity / 5 >= new_capacity)
1536             new_capacity *= 2; // ensure at least 20% reserve
1537         if (new_capacity > m_capacity_ctrl)
1538             return m_capacity_ctrl;
1539         return new_capacity;
1540     }
1541 
1542     /*! INTERNAL ONLY */
1543     void check_low_capacity(size_type n = 1) {
1544         size_type new_size = size() + n;
1545         size_type new_capacity = circular_buffer<T, Alloc>::capacity();
1546         if (new_size > new_capacity) {
1547             if (new_capacity == 0)
1548                 new_capacity = 1;
1549             for (; new_size > new_capacity; new_capacity *= 2) {}
1550             circular_buffer<T, Alloc>::set_capacity(
1551                 ensure_reserve(new_capacity, new_size));
1552         }
1553 #if BOOST_CB_ENABLE_DEBUG
1554         this->invalidate_iterators_except(end());
1555 #endif
1556     }
1557 
1558     /*! INTERNAL ONLY */
1559     void check_high_capacity() {
1560         size_type new_capacity = circular_buffer<T, Alloc>::capacity();
1561         while (new_capacity / 3 >= size()) { // (new_capacity / 3) -> avoid oscillations
1562             new_capacity /= 2;
1563             if (new_capacity <= m_capacity_ctrl.min_capacity()) {
1564                 new_capacity = m_capacity_ctrl.min_capacity();
1565                 break;
1566             }
1567         }
1568         circular_buffer<T, Alloc>::set_capacity(
1569             ensure_reserve(new_capacity, size()));
1570 #if BOOST_CB_ENABLE_DEBUG
1571         this->invalidate_iterators_except(end());
1572 #endif
1573     }
1574 
1575     /*! INTERNAL ONLY */
1576     void reduce_capacity(const true_type&) {
1577         circular_buffer<T, Alloc>::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size()));
1578     }
1579 
1580     /*! INTERNAL ONLY */
1581     void reduce_capacity(const false_type&) {}
1582 
1583     /*! INTERNAL ONLY */
1584     static size_type init_capacity(const capacity_type& capacity_ctrl, size_type n) {
1585         BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for capacity lower than n
1586         return (std::max)(capacity_ctrl.min_capacity(), n);
1587     }
1588 
1589     /*! INTERNAL ONLY */
1590     template <class IntegralType>
1591     static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType,
1592         const true_type&) {
1593         return init_capacity(capacity_ctrl, static_cast<size_type>(n));
1594     }
1595 
1596     /*! INTERNAL ONLY */
1597     template <class Iterator>
1598     static size_type init_capacity(const capacity_type& capacity_ctrl, Iterator first, Iterator last,
1599         const false_type&) {
1600         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
1601 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
1602         return init_capacity(capacity_ctrl, first, last, std::iterator_traits<Iterator>::iterator_category());
1603 #else
1604         return init_capacity(
1605             capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
1606 #endif
1607     }
1608 
1609     /*! INTERNAL ONLY */
1610     template <class InputIterator>
1611     static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator,
1612         const std::input_iterator_tag&) {
1613         return capacity_ctrl.capacity();
1614     }
1615 
1616     /*! INTERNAL ONLY */
1617     template <class ForwardIterator>
1618     static size_type init_capacity(const capacity_type& capacity_ctrl, ForwardIterator first, ForwardIterator last,
1619         const std::forward_iterator_tag&) {
1620         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
1621         return (std::max)(capacity_ctrl.min_capacity(),
1622             (std::min)(capacity_ctrl.capacity(), static_cast<size_type>(std::distance(first, last))));
1623     }
1624 
1625     /*! INTERNAL ONLY */
1626     template <class IntegralType>
1627     void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
1628         insert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
1629     }
1630 
1631     /*! INTERNAL ONLY */
1632     template <class Iterator>
1633     void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
1634         size_type index = pos - begin();
1635         check_low_capacity(std::distance(first, last));
1636         circular_buffer<T, Alloc>::insert(begin() + index, first, last);
1637     }
1638 
1639     /*! INTERNAL ONLY */
1640     template <class IntegralType>
1641     void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
1642         rinsert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
1643     }
1644 
1645     /*! INTERNAL ONLY */
1646     template <class Iterator>
1647     void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
1648         size_type index = pos - begin();
1649         check_low_capacity(std::distance(first, last));
1650         circular_buffer<T, Alloc>::rinsert(begin() + index, first, last);
1651     }
1652 };
1653 
1654 // Non-member functions
1655 
1656 //! Test two space optimized circular buffers for equality.
1657 template <class T, class Alloc>
1658 inline bool operator == (const circular_buffer_space_optimized<T, Alloc>& lhs,
1659     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1660     return lhs.size() == rhs.size() &&
1661         std::equal(lhs.begin(), lhs.end(), rhs.begin());
1662 }
1663 
1664 //! Lexicographical comparison.
1665 template <class T, class Alloc>
1666 inline bool operator < (const circular_buffer_space_optimized<T, Alloc>& lhs,
1667     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1668     return std::lexicographical_compare(
1669         lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1670 }
1671 
1672 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
1673 
1674 //! Test two space optimized circular buffers for non-equality.
1675 template <class T, class Alloc>
1676 inline bool operator != (const circular_buffer_space_optimized<T, Alloc>& lhs,
1677     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1678     return !(lhs == rhs);
1679 }
1680 
1681 //! Lexicographical comparison.
1682 template <class T, class Alloc>
1683 inline bool operator > (const circular_buffer_space_optimized<T, Alloc>& lhs,
1684     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1685     return rhs < lhs;
1686 }
1687 
1688 //! Lexicographical comparison.
1689 template <class T, class Alloc>
1690 inline bool operator <= (const circular_buffer_space_optimized<T, Alloc>& lhs,
1691     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1692     return !(rhs < lhs);
1693 }
1694 
1695 //! Lexicographical comparison.
1696 template <class T, class Alloc>
1697 inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
1698     const circular_buffer_space_optimized<T, Alloc>& rhs) {
1699     return !(lhs < rhs);
1700 }
1701 
1702 //! Swap the contents of two space optimized circular buffers.
1703 template <class T, class Alloc>
1704 inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
1705     circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
1706     lhs.swap(rhs);
1707 }
1708 
1709 #endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
1710 
1711 } // namespace boost
1712 
1713 #endif // #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)