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