comparison DEPENDENCIES/generic/include/boost/circular_buffer/space_optimized.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 // Implementation of the circular buffer adaptor.
2
3 // Copyright (c) 2003-2008 Jan Gaspar
4 // Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation.
5 // Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
6
7 // Use, modification, and distribution is subject to the Boost Software
8 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
12 #define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
13
14 #if defined(_MSC_VER) && _MSC_VER >= 1200
15 #pragma once
16 #endif
17
18 #include <boost/type_traits/is_same.hpp>
19 #include <boost/detail/workaround.hpp>
20
21 namespace boost {
22
23 /*!
24 \class circular_buffer_space_optimized
25 \brief Space optimized circular buffer container adaptor.
26 <code>T</code> must be a copyable class or must have an noexcept move constructor
27 and move assignment operator.
28 */
29 template <class T, class Alloc>
30 class circular_buffer_space_optimized :
31 /*! \cond */
32 #if BOOST_CB_ENABLE_DEBUG
33 public
34 #endif
35 /*! \endcond */
36 circular_buffer<T, Alloc> {
37 public:
38 // Typedefs
39
40 typedef typename circular_buffer<T, Alloc>::value_type value_type;
41 typedef typename circular_buffer<T, Alloc>::pointer pointer;
42 typedef typename circular_buffer<T, Alloc>::const_pointer const_pointer;
43 typedef typename circular_buffer<T, Alloc>::reference reference;
44 typedef typename circular_buffer<T, Alloc>::const_reference const_reference;
45 typedef typename circular_buffer<T, Alloc>::size_type size_type;
46 typedef typename circular_buffer<T, Alloc>::difference_type difference_type;
47 typedef typename circular_buffer<T, Alloc>::allocator_type allocator_type;
48 typedef typename circular_buffer<T, Alloc>::const_iterator const_iterator;
49 typedef typename circular_buffer<T, Alloc>::iterator iterator;
50 typedef typename circular_buffer<T, Alloc>::const_reverse_iterator const_reverse_iterator;
51 typedef typename circular_buffer<T, Alloc>::reverse_iterator reverse_iterator;
52 typedef typename circular_buffer<T, Alloc>::array_range array_range;
53 typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range;
54 typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type;
55 typedef typename circular_buffer<T, Alloc>::rvalue_type rvalue_type;
56 //typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
57
58 /* <pre> is not passed through to html or pdf. So <br> is used in code section below. Ugly :-(
59 Ideally want a link to capacity_control, but this would require include details
60 and this would expose all the functions in details.
61 There must be a better way of doing this.
62 */
63
64 /*! Capacity controller of the space optimized circular buffer.
65
66 \see capacity_control in details.hpp.
67 <p>
68 <code>
69 class capacity_control<br>
70 {<br>
71 size_type m_capacity; // Available capacity.<br>
72 size_type m_min_capacity; // Minimum capacity.<br>
73 public:<br>
74 capacity_control(size_type capacity, size_type min_capacity = 0)<br>
75 : m_capacity(capacity), m_min_capacity(min_capacity)<br>
76 {};<br>
77 size_type %capacity() const { return m_capacity; }<br>
78 size_type min_capacity() const { return m_min_capacity; }<br>
79 operator size_type() const { return m_capacity; }<br>
80 };<br>
81 </code>
82 </p>
83
84
85 <p>Always
86 <code>capacity >= min_capacity</code>.
87 </p>
88 <p>
89 The <code>capacity()</code> represents the capacity
90 of the <code>circular_buffer_space_optimized</code> and
91 the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.
92 </p>
93 <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
94 <code>size_type</code>-like types which ensures compatibility of creating an instance of the
95 <code>circular_buffer_space_optimized</code> with other STL containers.
96
97 On the other hand the operator <code>%size_type()</code>
98 provides implicit conversion to the <code>size_type</code> which allows to treat the
99 capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
100 <code>circular_buffer</a></code>.
101 </p>
102 */
103 typedef cb_details::capacity_control<size_type> capacity_type;
104
105 // Inherited
106
107 using circular_buffer<T, Alloc>::get_allocator;
108 using circular_buffer<T, Alloc>::begin;
109 using circular_buffer<T, Alloc>::end;
110 using circular_buffer<T, Alloc>::rbegin;
111 using circular_buffer<T, Alloc>::rend;
112 using circular_buffer<T, Alloc>::at;
113 using circular_buffer<T, Alloc>::front;
114 using circular_buffer<T, Alloc>::back;
115 using circular_buffer<T, Alloc>::array_one;
116 using circular_buffer<T, Alloc>::array_two;
117 using circular_buffer<T, Alloc>::linearize;
118 using circular_buffer<T, Alloc>::is_linearized;
119 using circular_buffer<T, Alloc>::rotate;
120 using circular_buffer<T, Alloc>::size;
121 using circular_buffer<T, Alloc>::max_size;
122 using circular_buffer<T, Alloc>::empty;
123
124 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
125 reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); }
126 const_reference operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
127 #else
128 using circular_buffer<T, Alloc>::operator[];
129 #endif
130
131 private:
132 // Member variables
133
134 //! The capacity controller of the space optimized circular buffer.
135 capacity_type m_capacity_ctrl;
136
137 public:
138 // Overridden
139
140 //! Is the <code>circular_buffer_space_optimized</code> full?
141 /*!
142 \return <code>true</code> if the number of elements stored in the <code>circular_buffer_space_optimized</code>
143 equals the capacity of the <code>circular_buffer_space_optimized</code>; <code>false</code> otherwise.
144 \throws Nothing.
145 \par Exception Safety
146 No-throw.
147 \par Iterator Invalidation
148 Does not invalidate any iterators.
149 \par Complexity
150 Constant (in the size of the <code>circular_buffer_space_optimized</code>).
151 \sa <code>empty()</code>
152 */
153 bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); }
154
155 /*! \brief Get the maximum number of elements which can be inserted into the
156 <code>circular_buffer_space_optimized</code> without overwriting any of already stored elements.
157 \return <code>capacity().%capacity() - size()</code>
158 \throws Nothing.
159 \par Exception Safety
160 No-throw.
161 \par Iterator Invalidation
162 Does not invalidate any iterators.
163 \par Complexity
164 Constant (in the size of the <code>circular_buffer_space_optimized</code>).
165 \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
166 */
167 size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); }
168
169 //! Get the capacity of the <code>circular_buffer_space_optimized</code>.
170 /*!
171 \return The capacity controller representing the maximum number of elements which can be stored in the
172 <code>circular_buffer_space_optimized</code> and the minimal allocated size of the internal buffer.
173 \throws Nothing.
174 \par Exception Safety
175 No-throw.
176 \par Iterator Invalidation
177 Does not invalidate any iterators.
178 \par Complexity
179 Constant (in the size of the <code>circular_buffer_space_optimized</code>).
180 \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
181 <code>set_capacity(const capacity_type&)</code>
182 */
183 const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; }
184
185 #if defined(BOOST_CB_TEST)
186
187 // Return the current capacity of the adapted circular buffer.
188 /*
189 \note This method is not intended to be used directly by the user.
190 It is defined only for testing purposes.
191 */
192 size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer<T, Alloc>::capacity(); }
193
194 #endif // #if defined(BOOST_CB_TEST)
195
196 /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
197 <code>circular_buffer_space_optimized</code>.
198 \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl.capacity()</code><br><br>
199 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
200 than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code> <b>last</b>
201 elements will be removed and the new size will be equal to <code>capacity_ctrl.capacity()</code>.<br><br>
202 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
203 than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
204 necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
205 \param capacity_ctrl The new capacity controller.
206 \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
207 used).
208 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
209 \par Exception Safety
210 Strong.
211 \par Iterator Invalidation
212 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
213 equal to <code>end()</code>).
214 \par Complexity
215 Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
216 \note To explicitly clear the extra allocated memory use the <b>shrink-to-fit</b> technique:<br><br>
217 <code>%boost::%circular_buffer_space_optimized\<int\> cb(1000);<br>
218 ...<br>
219 %boost::%circular_buffer_space_optimized\<int\>(cb).swap(cb);</code><br><br>
220 For more information about the shrink-to-fit technique in STL see
221 <a href="http://www.gotw.ca/gotw/054.htm">http://www.gotw.ca/gotw/054.htm</a>.
222 \sa <code>rset_capacity(const capacity_type&)</code>,
223 <code>\link resize() resize(size_type, const_reference)\endlink</code>
224 */
225 void set_capacity(const capacity_type& capacity_ctrl) {
226 m_capacity_ctrl = capacity_ctrl;
227 if (capacity_ctrl < size()) {
228 iterator e = end();
229 circular_buffer<T, Alloc>::erase(e - (size() - capacity_ctrl), e);
230 }
231 adjust_min_capacity();
232 }
233
234 //! Change the size of the <code>circular_buffer_space_optimized</code>.
235 /*!
236 \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
237 If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
238 <b>back</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
239 size. In the case the resulting size exceeds the current capacity the capacity will be set to
240 <code>new_size</code>.<br><br>
241 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
242 than the desired new size then number of <code>[size() - new_size]</code> <b>last</b> elements will be
243 removed. (The capacity will remain unchanged.)<br><br>
244 The amount of allocated memory in the internal buffer may be accommodated as necessary.
245 \param new_size The new size.
246 \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
247 the requested size. (See the <i>Effect</i>.)
248 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
249 used).
250 Whatever <code>T::T(const T&)</code> throws.
251 \par Exception Safety
252 Basic.
253 \par Iterator Invalidation
254 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
255 equal to <code>end()</code>).
256 \par Complexity
257 Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
258 \sa <code>\link rresize() rresize(size_type, const_reference)\endlink</code>,
259 <code>set_capacity(const capacity_type&)</code>
260 */
261 void resize(size_type new_size, param_value_type item = value_type()) {
262 if (new_size > size()) {
263 if (new_size > m_capacity_ctrl)
264 m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
265 insert(end(), new_size - size(), item);
266 } else {
267 iterator e = end();
268 erase(e - (size() - new_size), e);
269 }
270 }
271
272 /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
273 <code>circular_buffer_space_optimized</code>.
274 \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl</code><br><br>
275 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
276 than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code>
277 <b>first</b> elements will be removed and the new size will be equal to
278 <code>capacity_ctrl.capacity()</code>.<br><br>
279 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
280 than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
281 necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
282 \param capacity_ctrl The new capacity controller.
283 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
284 used).
285 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
286 \par Exception Safety
287 Strong.
288 \par Iterator Invalidation
289 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
290 equal to <code>end()</code>).
291 \par Complexity
292 Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
293 \sa <code>set_capacity(const capacity_type&)</code>,
294 <code>\link rresize() rresize(size_type, const_reference)\endlink</code>
295 */
296 void rset_capacity(const capacity_type& capacity_ctrl) {
297 m_capacity_ctrl = capacity_ctrl;
298 if (capacity_ctrl < size()) {
299 iterator b = begin();
300 circular_buffer<T, Alloc>::rerase(b, b + (size() - capacity_ctrl));
301 }
302 adjust_min_capacity();
303 }
304
305 //! Change the size of the <code>circular_buffer_space_optimized</code>.
306 /*!
307 \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
308 If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
309 <b>front</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
310 size. In the case the resulting size exceeds the current capacity the capacity will be set to
311 <code>new_size</code>.<br><br>
312 If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
313 than the desired new size then number of <code>[size() - new_size]</code> <b>first</b> elements will be
314 removed. (The capacity will remain unchanged.)<br><br>
315 The amount of allocated memory in the internal buffer may be accommodated as necessary.
316 \param new_size The new size.
317 \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
318 the requested size. (See the <i>Effect</i>.)
319 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
320 used).
321 Whatever <code>T::T(const T&)</code> throws.
322 \par Exception Safety
323 Basic.
324 \par Iterator Invalidation
325 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
326 equal to <code>end()</code>).
327 \par Complexity
328 Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
329 \sa <code>\link resize() resize(size_type, const_reference)\endlink</code>,
330 <code>rset_capacity(const capacity_type&)</code>
331 */
332 void rresize(size_type new_size, param_value_type item = value_type()) {
333 if (new_size > size()) {
334 if (new_size > m_capacity_ctrl)
335 m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
336 rinsert(begin(), new_size - size(), item);
337 } else {
338 rerase(begin(), end() - new_size);
339 }
340 }
341
342 //! Create an empty space optimized circular buffer with zero capacity.
343 /*!
344 \post <code>capacity().%capacity() == 0 \&\& capacity().min_capacity() == 0 \&\& size() == 0</code>
345 \param alloc The allocator.
346 \throws Nothing.
347 \par Complexity
348 Constant.
349 \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space
350 optimized circular buffer with zero capacity.
351 */
352 explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
353 : circular_buffer<T, Alloc>(0, alloc)
354 , m_capacity_ctrl(0) {}
355
356 //! Create an empty space optimized circular buffer with the specified capacity.
357 /*!
358 \post <code>capacity() == capacity_ctrl \&\& size() == 0</code><br><br>
359 The amount of allocated memory in the internal buffer is <code>capacity_ctrl.min_capacity()</code>.
360 \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
361 the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
362 internal buffer.
363 \param alloc The allocator.
364 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
365 used).
366 \par Complexity
367 Constant.
368 */
369 explicit circular_buffer_space_optimized(capacity_type capacity_ctrl,
370 const allocator_type& alloc = allocator_type())
371 : circular_buffer<T, Alloc>(capacity_ctrl.min_capacity(), alloc)
372 , m_capacity_ctrl(capacity_ctrl) {}
373
374 /*! \brief Create a full space optimized circular buffer with the specified capacity filled with
375 <code>capacity_ctrl.%capacity()</code> copies of <code>item</code>.
376 \post <code>capacity() == capacity_ctrl \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ...
377 \&\& (*this) [capacity_ctrl.%capacity() - 1] == item </code><br><br>
378 The amount of allocated memory in the internal buffer is <code>capacity_ctrl.capacity()</code>.
379 \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
380 the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
381 internal buffer.
382 \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
383 \param alloc The allocator.
384 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
385 used).
386 \throws Whatever <code>T::T(const T&)</code> throws.
387 \par Complexity
388 Linear (in the <code>capacity_ctrl.%capacity()</code>).
389 */
390 circular_buffer_space_optimized(capacity_type capacity_ctrl, param_value_type item,
391 const allocator_type& alloc = allocator_type())
392 : circular_buffer<T, Alloc>(capacity_ctrl.capacity(), item, alloc)
393 , m_capacity_ctrl(capacity_ctrl) {}
394
395 /*! \brief Create a space optimized circular buffer with the specified capacity filled with <code>n</code> copies
396 of <code>item</code>.
397 \pre <code>capacity_ctrl.%capacity() >= n</code>
398 \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
399 \&\& ... \&\& (*this)[n - 1] == item</code><br><br>
400 The amount of allocated memory in the internal buffer is
401 <code>max[n, capacity_ctrl.min_capacity()]</code>.
402 \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
403 the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
404 internal buffer.
405 \param n The number of elements the created <code>circular_buffer_space_optimized</code> will be filled with.
406 \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
407 \param alloc The allocator.
408 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
409 used).
410 Whatever <code>T::T(const T&)</code> throws.
411 \par Complexity
412 Linear (in the <code>n</code>).
413 */
414 circular_buffer_space_optimized(capacity_type capacity_ctrl, size_type n, param_value_type item,
415 const allocator_type& alloc = allocator_type())
416 : circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
417 , m_capacity_ctrl(capacity_ctrl) {}
418
419 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
420
421 /*! \cond */
422 circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
423 : circular_buffer<T, Alloc>(cb.begin(), cb.end())
424 , m_capacity_ctrl(cb.m_capacity_ctrl) {}
425
426 template <class InputIterator>
427 circular_buffer_space_optimized(InputIterator first, InputIterator last)
428 : circular_buffer<T, Alloc>(first, last)
429 , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
430
431 template <class InputIterator>
432 circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last)
433 : circular_buffer<T, Alloc>(
434 init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
435 first, last)
436 , m_capacity_ctrl(capacity_ctrl) {
437 reduce_capacity(
438 is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
439 }
440 /*! \endcond */
441
442 #else
443
444 //! The copy constructor.
445 /*!
446 Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
447 \post <code>*this == cb</code><br><br>
448 The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
449 \param cb The <code>circular_buffer_space_optimized</code> to be copied.
450 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
451 used).
452 Whatever <code>T::T(const T&)</code> throws.
453 \par Complexity
454 Linear (in the size of <code>cb</code>).
455 */
456 circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
457 : circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
458 , m_capacity_ctrl(cb.m_capacity_ctrl) {}
459
460 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
461 //! The move constructor.
462 /*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>,
463 leaving <code>cb</code> empty.
464 \pre C++ compiler with rvalue references support.
465 \post <code>cb.empty()</code>
466 \param cb <code>circular_buffer</code> to 'steal' value from.
467 \throws Nothing.
468 \par Constant.
469 */
470 circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
471 : circular_buffer<T, Alloc>()
472 , m_capacity_ctrl(0) {
473 cb.swap(*this);
474 }
475 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
476
477 //! Create a full space optimized circular buffer filled with a copy of the range.
478 /*!
479 \pre Valid range <code>[first, last)</code>.<br>
480 <code>first</code> and <code>last</code> have to meet the requirements of
481 <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
482 \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
483 full() \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\&
484 (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
485 The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
486 \param first The beginning of the range to be copied.
487 \param last The end of the range to be copied.
488 \param alloc The allocator.
489 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
490 used).
491 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept
492 and <code>InputIterator</code> is a move iterator.
493 \par Complexity
494 Linear (in the <code>std::distance(first, last)</code>).
495 */
496 template <class InputIterator>
497 circular_buffer_space_optimized(InputIterator first, InputIterator last,
498 const allocator_type& alloc = allocator_type())
499 : circular_buffer<T, Alloc>(first, last, alloc)
500 , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
501
502 /*! \brief Create a space optimized circular buffer with the specified capacity (and the minimal guaranteed amount
503 of allocated memory) filled with a copy of the range.
504 \pre Valid range <code>[first, last)</code>.<br>
505 <code>first</code> and <code>last</code> have to meet the requirements of
506 <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
507 \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& (*this)[0]==
508 *(last - capacity_ctrl.%capacity()) \&\& (*this)[1] == *(last - capacity_ctrl.%capacity() + 1) \&\& ...
509 \&\& (*this)[capacity_ctrl.%capacity() - 1] == *(last - 1)</code><br><br>
510 If the number of items to be copied from the range <code>[first, last)</code> is greater than the
511 specified <code>capacity_ctrl.%capacity()</code> then only elements from the range
512 <code>[last - capacity_ctrl.%capacity(), last)</code> will be copied.<br><br>
513 The amount of allocated memory in the internal buffer is <code>max[capacity_ctrl.min_capacity(),
514 min[capacity_ctrl.%capacity(), std::distance(first, last)]]</code>.
515 \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
516 the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
517 internal buffer.
518 \param first The beginning of the range to be copied.
519 \param last The end of the range to be copied.
520 \param alloc The allocator.
521 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
522 used).
523 Whatever <code>T::T(const T&)</code> throws.
524 \par Complexity
525 Linear (in <code>std::distance(first, last)</code>; in
526 <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
527 is a <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
528 */
529 template <class InputIterator>
530 circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last,
531 const allocator_type& alloc = allocator_type())
532 : circular_buffer<T, Alloc>(
533 init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
534 first, last, alloc)
535 , m_capacity_ctrl(capacity_ctrl) {
536 reduce_capacity(
537 is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
538 }
539
540 #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
541
542 #if defined(BOOST_CB_NEVER_DEFINED)
543 // This section will never be compiled - the default destructor will be generated instead.
544 // Declared only for documentation purpose.
545
546 //! The destructor.
547 /*!
548 Destroys the <code>circular_buffer_space_optimized</code>.
549 \throws Nothing.
550 \par Iterator Invalidation
551 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (including
552 iterators equal to <code>end()</code>).
553 \par Complexity
554 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
555 \sa <code>clear()</code>
556 */
557 ~circular_buffer_space_optimized();
558
559 //! no-comment
560 void erase_begin(size_type n);
561
562 //! no-comment
563 void erase_end(size_type n);
564
565 #endif // #if defined(BOOST_CB_NEVER_DEFINED)
566
567 //! The assign operator.
568 /*!
569 Makes this <code>circular_buffer_space_optimized</code> to become a copy of the specified
570 <code>circular_buffer_space_optimized</code>.
571 \post <code>*this == cb</code><br><br>
572 The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
573 \param cb The <code>circular_buffer_space_optimized</code> to be copied.
574 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
575 used).
576 \throws Whatever <code>T::T(const T&)</code> throws.
577 \par Exception Safety
578 Strong.
579 \par Iterator Invalidation
580 Invalidates all iterators pointing to this <code>circular_buffer_space_optimized</code> (except iterators
581 equal to <code>end()</code>).
582 \par Complexity
583 Linear (in the size of <code>cb</code>).
584 \sa <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
585 <code>\link assign(capacity_type, size_type, param_value_type)
586 assign(capacity_type, size_type, const_reference)\endlink</code>,
587 <code>assign(InputIterator, InputIterator)</code>,
588 <code>assign(capacity_type, InputIterator, InputIterator)</code>
589 */
590 circular_buffer_space_optimized<T, Alloc>& operator = (const circular_buffer_space_optimized<T, Alloc>& cb) {
591 if (this == &cb)
592 return *this;
593 circular_buffer<T, Alloc>::assign(cb.begin(), cb.end());
594 m_capacity_ctrl = cb.m_capacity_ctrl;
595 return *this;
596 }
597
598 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
599 /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
600 \pre C++ compiler with rvalue references support.
601 \post <code>cb.empty()</code>
602 \param cb <code>circular_buffer</code> to 'steal' value from.
603 \throws Nothing.
604 \par Complexity
605 Constant.
606 */
607 circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
608 cb.swap(*this); // now `this` holds `cb`
609 circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
610 .swap(cb); // makes `cb` empty
611 return *this;
612 }
613 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
614
615
616 //! Assign <code>n</code> items into the space optimized circular buffer.
617 /*!
618 The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
619 <code>n</code> copies of the <code>item</code>.
620 \post <code>capacity().%capacity() == n \&\& capacity().min_capacity() == 0 \&\& size() == n \&\& (*this)[0] ==
621 item \&\& (*this)[1] == item \&\& ... \&\& (*this) [n - 1] == item</code><br><br>
622 The amount of allocated memory in the internal buffer is <code>n</code>.
623 \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
624 \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
625 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
626 used).
627 Whatever <code>T::T(const T&)</code> throws.
628 \par Exception Safety
629 Basic.
630 \par Iterator Invalidation
631 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
632 equal to <code>end()</code>).
633 \par Complexity
634 Linear (in the <code>n</code>).
635 \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
636 <code>\link assign(capacity_type, size_type, param_value_type)
637 assign(capacity_type, size_type, const_reference)\endlink</code>,
638 <code>assign(InputIterator, InputIterator)</code>,
639 <code>assign(capacity_type, InputIterator, InputIterator)</code>
640 */
641 void assign(size_type n, param_value_type item) {
642 circular_buffer<T, Alloc>::assign(n, item);
643 m_capacity_ctrl = capacity_type(n);
644 }
645
646 //! Assign <code>n</code> items into the space optimized circular buffer specifying the capacity.
647 /*!
648 The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
649 content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with <code>n</code>
650 copies of the <code>item</code>.
651 \pre <code>capacity_ctrl.%capacity() >= n</code>
652 \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
653 \&\& ... \&\& (*this) [n - 1] == item </code><br><br>
654 The amount of allocated memory will be <code>max[n, capacity_ctrl.min_capacity()]</code>.
655 \param capacity_ctrl The new capacity controller.
656 \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
657 \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
658 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
659 used).
660 Whatever <code>T::T(const T&)</code> throws.
661 \par Exception Safety
662 Basic.
663 \par Iterator Invalidation
664 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
665 equal to <code>end()</code>).
666 \par Complexity
667 Linear (in the <code>n</code>).
668 \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
669 <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
670 <code>assign(InputIterator, InputIterator)</code>,
671 <code>assign(capacity_type, InputIterator, InputIterator)</code>
672 */
673 void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) {
674 BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for new capacity lower than n
675 circular_buffer<T, Alloc>::assign((std::max)(capacity_ctrl.min_capacity(), n), n, item);
676 m_capacity_ctrl = capacity_ctrl;
677 }
678
679 //! Assign a copy of the range into the space optimized circular buffer.
680 /*!
681 The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
682 elements from the specified range.
683 \pre Valid range <code>[first, last)</code>.<br>
684 <code>first</code> and <code>last</code> have to meet the requirements of
685 <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
686 \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
687 size() == std::distance(first, last) \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ...
688 \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
689 The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
690 \param first The beginning of the range to be copied.
691 \param last The end of the range to be copied.
692 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
693 used).
694 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
695 <code>InputIterator</code> is a move iterator.
696 \par Exception Safety
697 Basic.
698 \par Iterator Invalidation
699 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
700 equal to <code>end()</code>).
701 \par Complexity
702 Linear (in the <code>std::distance(first, last)</code>).
703 \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
704 <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
705 <code>\link assign(capacity_type, size_type, param_value_type)
706 assign(capacity_type, size_type, const_reference)\endlink</code>,
707 <code>assign(capacity_type, InputIterator, InputIterator)</code>
708 */
709 template <class InputIterator>
710 void assign(InputIterator first, InputIterator last) {
711 circular_buffer<T, Alloc>::assign(first, last);
712 m_capacity_ctrl = capacity_type(circular_buffer<T, Alloc>::capacity());
713 }
714
715 //! Assign a copy of the range into the space optimized circular buffer specifying the capacity.
716 /*!
717 The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
718 content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
719 elements from the specified range.
720 \pre Valid range <code>[first, last)</code>.<br>
721 <code>first</code> and <code>last</code> have to meet the requirements of
722 <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
723 \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\&
724 (*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
725 (*this)[capacity - 1] == *(last - 1)</code><br><br>
726 If the number of items to be copied from the range <code>[first, last)</code> is greater than the
727 specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
728 will be copied.<br><br> The amount of allocated memory in the internal buffer is
729 <code>max[std::distance(first, last), capacity_ctrl.min_capacity()]</code>.
730 \param capacity_ctrl The new capacity controller.
731 \param first The beginning of the range to be copied.
732 \param last The end of the range to be copied.
733 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
734 used).
735 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
736 <code>InputIterator</code> is a move iterator.
737 \par Exception Safety
738 Basic.
739 \par Iterator Invalidation
740 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
741 equal to <code>end()</code>).
742 \par Complexity
743 Linear (in <code>std::distance(first, last)</code>; in
744 <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
745 is a <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
746 \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
747 <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
748 <code>\link assign(capacity_type, size_type, param_value_type)
749 assign(capacity_type, size_type, const_reference)\endlink</code>,
750 <code>assign(InputIterator, InputIterator)</code>
751 */
752 template <class InputIterator>
753 void assign(capacity_type capacity_ctrl, InputIterator first, InputIterator last) {
754 m_capacity_ctrl = capacity_ctrl;
755 circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
756 }
757
758 //! Swap the contents of two space-optimized circular-buffers.
759 /*!
760 \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
761 allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
762 allocated memory of <code>cb</code> and vice versa.
763 \param cb The <code>circular_buffer_space_optimized</code> whose content will be swapped.
764 \throws Nothing.
765 \par Exception Safety
766 No-throw.
767 \par Iterator Invalidation
768 Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
769 hand the iterators still point to the same elements but within another container. If you want to rely on
770 this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
771 otherwise an assertion will report an error if such invalidated iterator is used.)
772 \par Complexity
773 Constant (in the size of the <code>circular_buffer_space_optimized</code>).
774 \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>,
775 <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
776
777
778 */
779 // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103.
780
781 void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
782 std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
783 circular_buffer<T, Alloc>::swap(cb);
784 }
785
786 //! Insert a new element at the end of the space optimized circular buffer.
787 /*!
788 \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
789 If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
790 capacity is <code>0</code>, nothing will be inserted.<br><br>
791 The amount of allocated memory in the internal buffer may be predictively increased.
792 \param item The element to be inserted.
793 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
794 used).
795 Whatever <code>T::T(const T&)</code> throws.
796 \par Exception Safety
797 Basic.
798 \par Iterator Invalidation
799 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
800 equal to <code>end()</code>).
801 \par Complexity
802 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
803 \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
804 <code>pop_front()</code>
805 */
806 void push_back(param_value_type item) {
807 check_low_capacity();
808 circular_buffer<T, Alloc>::push_back(item);
809 }
810
811 //! Insert a new element at the end of the space optimized circular buffer.
812 /*!
813 \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
814 If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
815 capacity is <code>0</code>, nothing will be inserted.<br><br>
816 The amount of allocated memory in the internal buffer may be predictively increased.
817 \param item The element to be inserted.
818 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
819 used).
820 \par Exception Safety
821 Basic.
822 \par Iterator Invalidation
823 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
824 equal to <code>end()</code>).
825 \par Complexity
826 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
827 \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
828 <code>pop_front()</code>
829 */
830 void push_back(rvalue_type item) {
831 check_low_capacity();
832 circular_buffer<T, Alloc>::push_back(boost::move(item));
833 }
834
835 //! Insert a new element at the end of the space optimized circular buffer.
836 /*!
837 \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
838 If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
839 capacity is <code>0</code>, nothing will be inserted.<br><br>
840 The amount of allocated memory in the internal buffer may be predictively increased.
841 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
842 used).
843 Whatever <code>T::T()</code> throws.
844 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
845 \par Exception Safety
846 Basic.
847 \par Iterator Invalidation
848 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
849 equal to <code>end()</code>).
850 \par Complexity
851 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
852 \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
853 <code>pop_front()</code>
854 */
855 void push_back() {
856 check_low_capacity();
857 circular_buffer<T, Alloc>::push_back();
858 }
859
860 //! Insert a new element at the beginning of the space optimized circular buffer.
861 /*!
862 \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
863 If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
864 capacity is <code>0</code>, nothing will be inserted.<br><br>
865 The amount of allocated memory in the internal buffer may be predictively increased.
866 \param item The element to be inserted.
867 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
868 used).
869 Whatever <code>T::T(const T&)</code> throws.
870 \par Exception Safety
871 Basic.
872 \par Iterator Invalidation
873 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
874 equal to <code>end()</code>).
875 \par Complexity
876 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
877 \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
878 <code>pop_front()</code>
879 */
880 void push_front(param_value_type item) {
881 check_low_capacity();
882 circular_buffer<T, Alloc>::push_front(item);
883 }
884
885 //! Insert a new element at the beginning of the space optimized circular buffer.
886 /*!
887 \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
888 If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
889 capacity is <code>0</code>, nothing will be inserted.<br><br>
890 The amount of allocated memory in the internal buffer may be predictively increased.
891 \param item The element to be inserted.
892 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
893 used).
894 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
895 \par Exception Safety
896 Basic.
897 \par Iterator Invalidation
898 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
899 equal to <code>end()</code>).
900 \par Complexity
901 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
902 \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
903 <code>pop_front()</code>
904 */
905 void push_front(rvalue_type item) {
906 check_low_capacity();
907 circular_buffer<T, Alloc>::push_front(boost::move(item));
908 }
909
910 //! Insert a new element at the beginning of the space optimized circular buffer.
911 /*!
912 \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
913 If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
914 capacity is <code>0</code>, nothing will be inserted.<br><br>
915 The amount of allocated memory in the internal buffer may be predictively increased.
916 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
917 used).
918 Whatever <code>T::T()</code> throws.
919 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
920 \par Exception Safety
921 Basic.
922 \par Iterator Invalidation
923 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
924 equal to <code>end()</code>).
925 \par Complexity
926 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
927 \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
928 <code>pop_front()</code>
929 */
930 void push_front() {
931 check_low_capacity();
932 circular_buffer<T, Alloc>::push_front();
933 }
934
935 //! Remove the last element from the space optimized circular buffer.
936 /*!
937 \pre <code>!empty()</code>
938 \post The last element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
939 The amount of allocated memory in the internal buffer may be predictively decreased.
940 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
941 used).
942 \par Exception Safety
943 Basic.
944 \par Iterator Invalidation
945 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
946 equal to <code>end()</code>).
947 \par Complexity
948 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
949 \sa <code>pop_front()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
950 <code>\link push_front() push_front(const_reference)\endlink</code>
951 */
952 void pop_back() {
953 circular_buffer<T, Alloc>::pop_back();
954 check_high_capacity();
955 }
956
957 //! Remove the first element from the space optimized circular buffer.
958 /*!
959 \pre <code>!empty()</code>
960 \post The first element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
961 The amount of allocated memory in the internal buffer may be predictively decreased.
962 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
963 used).
964 \par Exception Safety
965 Basic.
966 \par Iterator Invalidation
967 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
968 equal to <code>end()</code>).
969 \par Complexity
970 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
971 \sa <code>pop_back()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
972 <code>\link push_front() push_front(const_reference)\endlink</code>
973 */
974 void pop_front() {
975 circular_buffer<T, Alloc>::pop_front();
976 check_high_capacity();
977 }
978
979 //! Insert an element at the specified position.
980 /*!
981 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
982 end.
983 \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
984 If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
985 the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
986 <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
987 nothing will be inserted.<br><br>
988 The amount of allocated memory in the internal buffer may be predictively increased.
989 \param pos An iterator specifying the position where the <code>item</code> will be inserted.
990 \param item The element to be inserted.
991 \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
992 the <i>Effect</i>.)
993 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
994 used).
995 Whatever <code>T::T(const T&)</code> throws.
996 Whatever <code>T::operator = (const T&)</code> throws.
997 \par Exception Safety
998 Basic.
999 \par Iterator Invalidation
1000 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1001 equal to <code>end()</code>).
1002 \par Complexity
1003 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1004 \sa <code>\link insert(iterator, size_type, param_value_type)
1005 insert(iterator, size_type, value_type)\endlink</code>,
1006 <code>insert(iterator, InputIterator, InputIterator)</code>,
1007 <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1008 <code>\link rinsert(iterator, size_type, param_value_type)
1009 rinsert(iterator, size_type, value_type)\endlink</code>,
1010 <code>rinsert(iterator, InputIterator, InputIterator)</code>
1011 */
1012 iterator insert(iterator pos, param_value_type item) {
1013 size_type index = pos - begin();
1014 check_low_capacity();
1015 return circular_buffer<T, Alloc>::insert(begin() + index, item);
1016 }
1017
1018 //! Insert an element at the specified position.
1019 /*!
1020 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1021 end.
1022 \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1023 If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
1024 the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1025 <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1026 nothing will be inserted.<br><br>
1027 The amount of allocated memory in the internal buffer may be predictively increased.
1028 \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1029 \param item The element to be inserted.
1030 \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1031 the <i>Effect</i>.)
1032 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1033 used).
1034 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1035 \par Exception Safety
1036 Basic.
1037 \par Iterator Invalidation
1038 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1039 equal to <code>end()</code>).
1040 \par Complexity
1041 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1042 \sa <code>\link insert(iterator, size_type, param_value_type)
1043 insert(iterator, size_type, value_type)\endlink</code>,
1044 <code>insert(iterator, InputIterator, InputIterator)</code>,
1045 <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1046 <code>\link rinsert(iterator, size_type, param_value_type)
1047 rinsert(iterator, size_type, value_type)\endlink</code>,
1048 <code>rinsert(iterator, InputIterator, InputIterator)</code>
1049 */
1050 iterator insert(iterator pos, rvalue_type item) {
1051 size_type index = pos - begin();
1052 check_low_capacity();
1053 return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
1054 }
1055
1056 //! Insert an element at the specified position.
1057 /*!
1058 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1059 end.
1060 \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1061 If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
1062 the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1063 <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1064 nothing will be inserted.<br><br>
1065 The amount of allocated memory in the internal buffer may be predictively increased.
1066 \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1067 \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1068 the <i>Effect</i>.)
1069 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1070 used).
1071 Whatever <code>T::T()</code> throws.
1072 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1073 \par Exception Safety
1074 Basic.
1075 \par Iterator Invalidation
1076 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1077 equal to <code>end()</code>).
1078 \par Complexity
1079 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1080 \sa <code>\link insert(iterator, size_type, param_value_type)
1081 insert(iterator, size_type, value_type)\endlink</code>,
1082 <code>insert(iterator, InputIterator, InputIterator)</code>,
1083 <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1084 <code>\link rinsert(iterator, size_type, param_value_type)
1085 rinsert(iterator, size_type, value_type)\endlink</code>,
1086 <code>rinsert(iterator, InputIterator, InputIterator)</code>
1087 */
1088 iterator insert(iterator pos) {
1089 size_type index = pos - begin();
1090 check_low_capacity();
1091 return circular_buffer<T, Alloc>::insert(begin() + index);
1092 }
1093
1094 //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
1095 /*!
1096 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1097 end.
1098 \post The number of <code>min[n, (pos - begin()) + reserve()]</code> elements will be inserted at the position
1099 <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0, n - reserve()]]</code> elements will
1100 be overwritten at the beginning of the <code>circular_buffer_space_optimized</code>.<br>(See
1101 <i>Example</i> for the explanation.)<br><br>
1102 The amount of allocated memory in the internal buffer may be predictively increased.
1103 \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
1104 \param n The number of <code>item</code>s the to be inserted.
1105 \param item The element whose copies will be inserted.
1106 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1107 used).
1108 Whatever <code>T::T(const T&)</code> throws.
1109 Whatever <code>T::operator = (const T&)</code> throws.
1110 \par Exception Safety
1111 Basic.
1112 \par Iterator Invalidation
1113 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1114 equal to <code>end()</code>).
1115 \par Complexity
1116 Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
1117 \par Example
1118 Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1119 internal buffer may look like the one below.<br><br>
1120 <code>|1|2|3|4| | |</code><br>
1121 <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
1122 <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
1123 <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
1124 the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
1125 <br>For comparison if the capacity would not be preserved the internal buffer would then result in
1126 <code>|1|2|0|0|0|0|0|3|4|</code>.
1127 \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1128 <code>insert(iterator, InputIterator, InputIterator)</code>,
1129 <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1130 <code>\link rinsert(iterator, size_type, param_value_type)
1131 rinsert(iterator, size_type, value_type)\endlink</code>,
1132 <code>rinsert(iterator, InputIterator, InputIterator)</code>
1133 */
1134 void insert(iterator pos, size_type n, param_value_type item) {
1135 size_type index = pos - begin();
1136 check_low_capacity(n);
1137 circular_buffer<T, Alloc>::insert(begin() + index, n, item);
1138 }
1139
1140 //! Insert the range <code>[first, last)</code> at the specified position.
1141 /*!
1142 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1143 end.<br>Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
1144 requirements of an <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
1145 \post Elements from the range
1146 <code>[first + max[0, distance(first, last) - (pos - begin()) - reserve()], last)</code> will be
1147 inserted at the position <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0,
1148 distance(first, last) - reserve()]]</code> elements will be overwritten at the beginning of the
1149 <code>circular_buffer_space_optimized</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
1150 The amount of allocated memory in the internal buffer may be predictively increased.
1151 \param pos An iterator specifying the position where the range will be inserted.
1152 \param first The beginning of the range to be inserted.
1153 \param last The end of the range to be inserted.
1154 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1155 used).
1156 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1157 \par Exception Safety
1158 Basic.
1159 \par Iterator Invalidation
1160 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1161 equal to <code>end()</code>).
1162 \par Complexity
1163 Linear (in <code>[size() + std::distance(first, last)]</code>; in
1164 <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
1165 <code>InputIterator</code> is a
1166 <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1167 \par Example
1168 Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1169 internal buffer may look like the one below.<br><br>
1170 <code>|1|2|3|4| | |</code><br>
1171 <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
1172 <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
1173 actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
1174 specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
1175 to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like
1176 this:<br><br><code>|6|7|8|9|3|4|</code><br><br>For comparison if the capacity would not be preserved the
1177 internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
1178 \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1179 <code>\link insert(iterator, size_type, param_value_type)
1180 insert(iterator, size_type, value_type)\endlink</code>, <code>\link rinsert(iterator, param_value_type)
1181 rinsert(iterator, value_type)\endlink</code>, <code>\link rinsert(iterator, size_type, param_value_type)
1182 rinsert(iterator, size_type, value_type)\endlink</code>,
1183 <code>rinsert(iterator, InputIterator, InputIterator)</code>
1184 */
1185 template <class InputIterator>
1186 void insert(iterator pos, InputIterator first, InputIterator last) {
1187 insert(pos, first, last, is_integral<InputIterator>());
1188 }
1189
1190 //! Insert an element before the specified position.
1191 /*!
1192 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1193 end.
1194 \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1195 If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1196 <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1197 <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1198 nothing will be inserted.<br><br>
1199 The amount of allocated memory in the internal buffer may be predictively increased.
1200 \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1201 \param item The element to be inserted.
1202 \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1203 the <i>Effect</i>.)
1204 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1205 used).
1206 Whatever <code>T::T(const T&)</code> throws.
1207 Whatever <code>T::operator = (const T&)</code> throws.
1208 \par Exception Safety
1209 Basic.
1210 \par Iterator Invalidation
1211 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1212 equal to <code>end()</code>).
1213 \par Complexity
1214 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1215 \sa <code>\link rinsert(iterator, size_type, param_value_type)
1216 rinsert(iterator, size_type, value_type)\endlink</code>,
1217 <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1218 <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1219 <code>\link insert(iterator, size_type, param_value_type)
1220 insert(iterator, size_type, value_type)\endlink</code>,
1221 <code>insert(iterator, InputIterator, InputIterator)</code>
1222 */
1223 iterator rinsert(iterator pos, param_value_type item) {
1224 size_type index = pos - begin();
1225 check_low_capacity();
1226 return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
1227 }
1228
1229 //! Insert an element before the specified position.
1230 /*!
1231 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1232 end.
1233 \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1234 If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1235 <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1236 <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1237 nothing will be inserted.<br><br>
1238 The amount of allocated memory in the internal buffer may be predictively increased.
1239 \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1240 \param item The element to be inserted.
1241 \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1242 the <i>Effect</i>.)
1243 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1244 used).
1245 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1246 \par Exception Safety
1247 Basic.
1248 \par Iterator Invalidation
1249 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1250 equal to <code>end()</code>).
1251 \par Complexity
1252 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1253 \sa <code>\link rinsert(iterator, size_type, param_value_type)
1254 rinsert(iterator, size_type, value_type)\endlink</code>,
1255 <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1256 <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1257 <code>\link insert(iterator, size_type, param_value_type)
1258 insert(iterator, size_type, value_type)\endlink</code>,
1259 <code>insert(iterator, InputIterator, InputIterator)</code>
1260 */
1261 iterator rinsert(iterator pos, rvalue_type item) {
1262 size_type index = pos - begin();
1263 check_low_capacity();
1264 return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
1265 }
1266
1267 //! Insert an element before the specified position.
1268 /*!
1269 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1270 end.
1271 \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1272 If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
1273 <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
1274 <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
1275 nothing will be inserted.<br><br>
1276 The amount of allocated memory in the internal buffer may be predictively increased.
1277 \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1278 \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1279 the <i>Effect</i>.)
1280 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1281 used).
1282 Whatever <code>T::T()</code> throws.
1283 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
1284 \par Exception Safety
1285 Basic.
1286 \par Iterator Invalidation
1287 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1288 equal to <code>end()</code>).
1289 \par Complexity
1290 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1291 \sa <code>\link rinsert(iterator, size_type, param_value_type)
1292 rinsert(iterator, size_type, value_type)\endlink</code>,
1293 <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1294 <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1295 <code>\link insert(iterator, size_type, param_value_type)
1296 insert(iterator, size_type, value_type)\endlink</code>,
1297 <code>insert(iterator, InputIterator, InputIterator)</code>
1298 */
1299 iterator rinsert(iterator pos) {
1300 size_type index = pos - begin();
1301 check_low_capacity();
1302 return circular_buffer<T, Alloc>::rinsert(begin() + index);
1303 }
1304
1305 //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
1306 /*!
1307 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1308 end.
1309 \post The number of <code>min[n, (end() - pos) + reserve()]</code> elements will be inserted before the
1310 position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0, n - reserve()]]</code> elements
1311 will be overwritten at the end of the <code>circular_buffer_space_optimized</code>.<br>(See
1312 <i>Example</i> for the explanation.)<br><br>
1313 The amount of allocated memory in the internal buffer may be predictively increased.
1314 \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
1315 \param n The number of <code>item</code>s the to be inserted.
1316 \param item The element whose copies will be inserted.
1317 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1318 used).
1319 Whatever <code>T::T(const T&)</code> throws.
1320 Whatever <code>T::operator = (const T&)</code> throws.
1321 \par Exception Safety
1322 Basic.
1323 \par Iterator Invalidation
1324 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1325 equal to <code>end()</code>).
1326 \par Complexity
1327 Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
1328 \par Example
1329 Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1330 internal buffer may look like the one below.<br><br>
1331 <code>|1|2|3|4| | |</code><br>
1332 <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
1333 <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
1334 <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
1335 the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
1336 <br>For comparison if the capacity would not be preserved the internal buffer would then result in
1337 <code>|1|2|0|0|0|0|0|3|4|</code>.
1338 \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1339 <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1340 <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1341 <code>\link insert(iterator, size_type, param_value_type)
1342 insert(iterator, size_type, value_type)\endlink</code>,
1343 <code>insert(iterator, InputIterator, InputIterator)</code>
1344 */
1345 void rinsert(iterator pos, size_type n, param_value_type item) {
1346 size_type index = pos - begin();
1347 check_low_capacity(n);
1348 circular_buffer<T, Alloc>::rinsert(begin() + index, n, item);
1349 }
1350
1351 //! Insert the range <code>[first, last)</code> before the specified position.
1352 /*!
1353 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
1354 end.<br>
1355 Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
1356 requirements of an <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
1357 \post Elements from the range
1358 <code>[first, last - max[0, distance(first, last) - (end() - pos) - reserve()])</code> will be inserted
1359 before the position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0,
1360 distance(first, last) - reserve()]]</code> elements will be overwritten at the end of the
1361 <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
1362 The amount of allocated memory in the internal buffer may be predictively increased.
1363 \param pos An iterator specifying the position where the range will be inserted.
1364 \param first The beginning of the range to be inserted.
1365 \param last The end of the range to be inserted.
1366 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1367 used).
1368 Whatever <code>T::T(const T&)</code> throws.
1369 Whatever <code>T::operator = (const T&)</code> throws.
1370 \par Exception Safety
1371 Basic.
1372 \par Iterator Invalidation
1373 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1374 equal to <code>end()</code>).
1375 \par Complexity
1376 Linear (in <code>[size() + std::distance(first, last)]</code>; in
1377 <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
1378 <code>InputIterator</code> is a
1379 <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1380 \par Example
1381 Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
1382 internal buffer may look like the one below.<br><br>
1383 <code>|1|2|3|4| | |</code><br>
1384 <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
1385 <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
1386 actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
1387 specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
1388 to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like
1389 this:<br><br><code>|1|2|5|6|7|8|</code><br><br>For comparison if the capacity would not be preserved the
1390 internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
1391 \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1392 <code>\link rinsert(iterator, size_type, param_value_type)
1393 rinsert(iterator, size_type, value_type)\endlink</code>, <code>\link insert(iterator, param_value_type)
1394 insert(iterator, value_type)\endlink</code>, <code>\link insert(iterator, size_type, param_value_type)
1395 insert(iterator, size_type, value_type)\endlink</code>,
1396 <code>insert(iterator, InputIterator, InputIterator)</code>
1397 */
1398 template <class InputIterator>
1399 void rinsert(iterator pos, InputIterator first, InputIterator last) {
1400 rinsert(pos, first, last, is_integral<InputIterator>());
1401 }
1402
1403 //! Remove an element at the specified position.
1404 /*!
1405 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
1406 an <code>end()</code>).
1407 \post The element at the position <code>pos</code> is removed.<br><br>
1408 The amount of allocated memory in the internal buffer may be predictively decreased.
1409 \param pos An iterator pointing at the element to be removed.
1410 \return Iterator to the first element remaining beyond the removed element or <code>end()</code> if no such
1411 element exists.
1412 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1413 used).
1414 Whatever <code>T::operator = (const T&)</code> throws or
1415 nothing if <code>T::operator = (T&&)</code> is noexcept.
1416 \par Exception Safety
1417 Basic.
1418 \par Iterator Invalidation
1419 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1420 equal to <code>end()</code>).
1421 \par Complexity
1422 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1423 \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1424 <code>rerase(iterator, iterator)</code>, <code>clear()</code>
1425 */
1426 iterator erase(iterator pos) {
1427 iterator it = circular_buffer<T, Alloc>::erase(pos);
1428 size_type index = it - begin();
1429 check_high_capacity();
1430 return begin() + index;
1431 }
1432
1433 //! Erase the range <code>[first, last)</code>.
1434 /*!
1435 \pre Valid range <code>[first, last)</code>.
1436 \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
1437 nothing is removed.)<br><br>
1438 The amount of allocated memory in the internal buffer may be predictively decreased.
1439 \param first The beginning of the range to be removed.
1440 \param last The end of the range to be removed.
1441 \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such
1442 element exists.
1443 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1444 used).
1445 Whatever <code>T::operator = (const T&)</code> throws or
1446 nothing if <code>T::operator = (T&&)</code> is noexcept.
1447 \par Exception Safety
1448 Basic.
1449 \par Iterator Invalidation
1450 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1451 equal to <code>end()</code>).
1452 \par Complexity
1453 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1454 \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
1455 <code>clear()</code>
1456 */
1457 iterator erase(iterator first, iterator last) {
1458 iterator it = circular_buffer<T, Alloc>::erase(first, last);
1459 size_type index = it - begin();
1460 check_high_capacity();
1461 return begin() + index;
1462 }
1463
1464 //! Remove an element at the specified position.
1465 /*!
1466 \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
1467 an <code>end()</code>).<br><br>
1468 The amount of allocated memory in the internal buffer may be predictively decreased.
1469 \post The element at the position <code>pos</code> is removed.
1470 \param pos An iterator pointing at the element to be removed.
1471 \return Iterator to the first element remaining in front of the removed element or <code>begin()</code> if no
1472 such element exists.
1473 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1474 used).
1475 Whatever <code>T::operator = (const T&)</code> throws or
1476 nothing if <code>T::operator = (T&&)</code> is noexcept.
1477 \par Exception Safety
1478 Basic.
1479 \par Iterator Invalidation
1480 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1481 equal to <code>end()</code>).
1482 \par Complexity
1483 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1484 \note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
1485 only for consistency with the base <code>circular_buffer</code>.
1486 \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
1487 <code>rerase(iterator, iterator)</code>, <code>clear()</code>
1488 */
1489 iterator rerase(iterator pos) {
1490 iterator it = circular_buffer<T, Alloc>::rerase(pos);
1491 size_type index = it - begin();
1492 check_high_capacity();
1493 return begin() + index;
1494 }
1495
1496 //! Erase the range <code>[first, last)</code>.
1497 /*!
1498 \pre Valid range <code>[first, last)</code>.
1499 \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
1500 nothing is removed.)<br><br>
1501 The amount of allocated memory in the internal buffer may be predictively decreased.
1502 \param first The beginning of the range to be removed.
1503 \param last The end of the range to be removed.
1504 \return Iterator to the first element remaining in front of the removed elements or <code>begin()</code> if no
1505 such element exists.
1506 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1507 used).
1508 Whatever <code>T::operator = (const T&)</code> throws or
1509 nothing if <code>T::operator = (T&&)</code> is noexcept.
1510 \par Exception Safety
1511 Basic.
1512 \par Iterator Invalidation
1513 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1514 equal to <code>end()</code>).
1515 \par Complexity
1516 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1517 \note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
1518 implemented only for consistency with the base
1519 <code><circular_buffer</code>.
1520 \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1521 <code>clear()</code>
1522 */
1523 iterator rerase(iterator first, iterator last) {
1524 iterator it = circular_buffer<T, Alloc>::rerase(first, last);
1525 size_type index = it - begin();
1526 check_high_capacity();
1527 return begin() + index;
1528 }
1529
1530 //! Remove all stored elements from the space optimized circular buffer.
1531 /*!
1532 \post <code>size() == 0</code><br><br>
1533 The amount of allocated memory in the internal buffer may be predictively decreased.
1534 \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1535 used).
1536 \par Exception Safety
1537 Basic.
1538 \par Iterator Invalidation
1539 Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
1540 equal to <code>end()</code>).
1541 \par Complexity
1542 Linear (in the size of the <code>circular_buffer_space_optimized</code>).
1543 \sa <code>~circular_buffer_space_optimized()</code>, <code>erase(iterator)</code>,
1544 <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
1545 <code>rerase(iterator, iterator)</code>
1546 */
1547 void clear() { erase(begin(), end()); }
1548
1549 private:
1550 // Helper methods
1551
1552 //! Adjust the amount of allocated memory.
1553 void adjust_min_capacity() {
1554 if (m_capacity_ctrl.min_capacity() > circular_buffer<T, Alloc>::capacity())
1555 circular_buffer<T, Alloc>::set_capacity(m_capacity_ctrl.min_capacity());
1556 else
1557 check_high_capacity();
1558 }
1559
1560 //! Ensure the reserve for possible growth up.
1561 size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const {
1562 if (buffer_size + new_capacity / 5 >= new_capacity)
1563 new_capacity *= 2; // ensure at least 20% reserve
1564 if (new_capacity > m_capacity_ctrl)
1565 return m_capacity_ctrl;
1566 return new_capacity;
1567 }
1568
1569 //! Check for low capacity.
1570 /*
1571 \post If the capacity is low it will be increased.
1572 */
1573 void check_low_capacity(size_type n = 1) {
1574 size_type new_size = size() + n;
1575 size_type new_capacity = circular_buffer<T, Alloc>::capacity();
1576 if (new_size > new_capacity) {
1577 if (new_capacity == 0)
1578 new_capacity = 1;
1579 for (; new_size > new_capacity; new_capacity *= 2) {}
1580 circular_buffer<T, Alloc>::set_capacity(
1581 ensure_reserve(new_capacity, new_size));
1582 }
1583 #if BOOST_CB_ENABLE_DEBUG
1584 this->invalidate_iterators_except(end());
1585 #endif
1586 }
1587
1588 //! Check for high capacity.
1589 /*
1590 \post If the capacity is high it will be decreased.
1591 */
1592 void check_high_capacity() {
1593 size_type new_capacity = circular_buffer<T, Alloc>::capacity();
1594 while (new_capacity / 3 >= size()) { // (new_capacity / 3) -> avoid oscillations
1595 new_capacity /= 2;
1596 if (new_capacity <= m_capacity_ctrl.min_capacity()) {
1597 new_capacity = m_capacity_ctrl.min_capacity();
1598 break;
1599 }
1600 }
1601 circular_buffer<T, Alloc>::set_capacity(
1602 ensure_reserve(new_capacity, size()));
1603 #if BOOST_CB_ENABLE_DEBUG
1604 this->invalidate_iterators_except(end());
1605 #endif
1606 }
1607
1608 //! Specialized method for reducing the capacity.
1609 void reduce_capacity(const true_type&) {
1610 circular_buffer<T, Alloc>::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size()));
1611 }
1612
1613 //! Specialized method for reducing the capacity.
1614 void reduce_capacity(const false_type&) {}
1615
1616 //! Determine the initial capacity.
1617 static size_type init_capacity(const capacity_type& capacity_ctrl, size_type n) {
1618 BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for capacity lower than n
1619 return (std::max)(capacity_ctrl.min_capacity(), n);
1620 }
1621
1622 //! Specialized method for determining the initial capacity.
1623 template <class IntegralType>
1624 static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType,
1625 const true_type&) {
1626 return init_capacity(capacity_ctrl, static_cast<size_type>(n));
1627 }
1628
1629 //! Specialized method for determining the initial capacity.
1630 template <class Iterator>
1631 static size_type init_capacity(const capacity_type& capacity_ctrl, Iterator first, Iterator last,
1632 const false_type&) {
1633 BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
1634 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
1635 return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
1636 #else
1637 return init_capacity(
1638 capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
1639 #endif
1640 }
1641
1642 //! Specialized method for determining the initial capacity.
1643 template <class InputIterator>
1644 static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator,
1645 const std::input_iterator_tag&) {
1646 return capacity_ctrl.capacity();
1647 }
1648
1649 //! Specialized method for determining the initial capacity.
1650 template <class ForwardIterator>
1651 static size_type init_capacity(const capacity_type& capacity_ctrl, ForwardIterator first, ForwardIterator last,
1652 const std::forward_iterator_tag&) {
1653 BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
1654 return (std::max)(capacity_ctrl.min_capacity(),
1655 (std::min)(capacity_ctrl.capacity(), static_cast<size_type>(std::distance(first, last))));
1656 }
1657
1658 //! Specialized insert method.
1659 template <class IntegralType>
1660 void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
1661 insert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
1662 }
1663
1664 //! Specialized insert method.
1665 template <class Iterator>
1666 void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
1667 size_type index = pos - begin();
1668 check_low_capacity(std::distance(first, last));
1669 circular_buffer<T, Alloc>::insert(begin() + index, first, last);
1670 }
1671
1672 //! Specialized rinsert method.
1673 template <class IntegralType>
1674 void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
1675 rinsert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
1676 }
1677
1678 //! Specialized rinsert method.
1679 template <class Iterator>
1680 void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
1681 size_type index = pos - begin();
1682 check_low_capacity(std::distance(first, last));
1683 circular_buffer<T, Alloc>::rinsert(begin() + index, first, last);
1684 }
1685 };
1686
1687 // Non-member functions
1688
1689 //! Test two space optimized circular buffers for equality.
1690 template <class T, class Alloc>
1691 inline bool operator == (const circular_buffer_space_optimized<T, Alloc>& lhs,
1692 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1693 return lhs.size() == rhs.size() &&
1694 std::equal(lhs.begin(), lhs.end(), rhs.begin());
1695 }
1696
1697 //! Lexicographical comparison.
1698 template <class T, class Alloc>
1699 inline bool operator < (const circular_buffer_space_optimized<T, Alloc>& lhs,
1700 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1701 return std::lexicographical_compare(
1702 lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1703 }
1704
1705 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
1706
1707 //! Test two space optimized circular buffers for non-equality.
1708 template <class T, class Alloc>
1709 inline bool operator != (const circular_buffer_space_optimized<T, Alloc>& lhs,
1710 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1711 return !(lhs == rhs);
1712 }
1713
1714 //! Lexicographical comparison.
1715 template <class T, class Alloc>
1716 inline bool operator > (const circular_buffer_space_optimized<T, Alloc>& lhs,
1717 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1718 return rhs < lhs;
1719 }
1720
1721 //! Lexicographical comparison.
1722 template <class T, class Alloc>
1723 inline bool operator <= (const circular_buffer_space_optimized<T, Alloc>& lhs,
1724 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1725 return !(rhs < lhs);
1726 }
1727
1728 //! Lexicographical comparison.
1729 template <class T, class Alloc>
1730 inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
1731 const circular_buffer_space_optimized<T, Alloc>& rhs) {
1732 return !(lhs < rhs);
1733 }
1734
1735 //! Swap the contents of two space optimized circular buffers.
1736 template <class T, class Alloc>
1737 inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
1738 circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
1739 lhs.swap(rhs);
1740 }
1741
1742 #endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
1743
1744 } // namespace boost
1745
1746 #endif // #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)