|
||||
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)
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |