Branch data Line data Source code
1 : : // Vector implementation (out of line) -*- C++ -*-
2 : :
3 : : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 : : // Free Software Foundation, Inc.
5 : : //
6 : : // This file is part of the GNU ISO C++ Library. This library is free
7 : : // software; you can redistribute it and/or modify it under the
8 : : // terms of the GNU General Public License as published by the
9 : : // Free Software Foundation; either version 2, or (at your option)
10 : : // any later version.
11 : :
12 : : // This library is distributed in the hope that it will be useful,
13 : : // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : // GNU General Public License for more details.
16 : :
17 : : // You should have received a copy of the GNU General Public License along
18 : : // with this library; see the file COPYING. If not, write to the Free
19 : : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 : : // USA.
21 : :
22 : : // As a special exception, you may use this file as part of a free software
23 : : // library without restriction. Specifically, if other files instantiate
24 : : // templates or use macros or inline functions from this file, or you compile
25 : : // this file and link it with other files to produce an executable, this
26 : : // file does not by itself cause the resulting executable to be covered by
27 : : // the GNU General Public License. This exception does not however
28 : : // invalidate any other reasons why the executable file might be covered by
29 : : // the GNU General Public License.
30 : :
31 : : /*
32 : : *
33 : : * Copyright (c) 1994
34 : : * Hewlett-Packard Company
35 : : *
36 : : * Permission to use, copy, modify, distribute and sell this software
37 : : * and its documentation for any purpose is hereby granted without fee,
38 : : * provided that the above copyright notice appear in all copies and
39 : : * that both that copyright notice and this permission notice appear
40 : : * in supporting documentation. Hewlett-Packard Company makes no
41 : : * representations about the suitability of this software for any
42 : : * purpose. It is provided "as is" without express or implied warranty.
43 : : *
44 : : *
45 : : * Copyright (c) 1996
46 : : * Silicon Graphics Computer Systems, Inc.
47 : : *
48 : : * Permission to use, copy, modify, distribute and sell this software
49 : : * and its documentation for any purpose is hereby granted without fee,
50 : : * provided that the above copyright notice appear in all copies and
51 : : * that both that copyright notice and this permission notice appear
52 : : * in supporting documentation. Silicon Graphics makes no
53 : : * representations about the suitability of this software for any
54 : : * purpose. It is provided "as is" without express or implied warranty.
55 : : */
56 : :
57 : : /** @file vector.tcc
58 : : * This is an internal header file, included by other library headers.
59 : : * You should not attempt to use it directly.
60 : : */
61 : :
62 : : #ifndef _VECTOR_TCC
63 : : #define _VECTOR_TCC 1
64 : :
65 : : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
66 : :
67 : : template<typename _Tp, typename _Alloc>
68 : : void
69 : : vector<_Tp, _Alloc>::
70 : 0 : reserve(size_type __n)
71 : : {
72 [ # # ]: 0 : if (__n > this->max_size())
73 : 0 : __throw_length_error(__N("vector::reserve"));
74 [ # # ]: 0 : if (this->capacity() < __n)
75 : : {
76 : 0 : const size_type __old_size = size();
77 : : pointer __tmp = _M_allocate_and_copy(__n,
78 : : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start),
79 : 0 : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish));
80 : 0 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
81 : : _M_get_Tp_allocator());
82 : 0 : _M_deallocate(this->_M_impl._M_start,
83 : : this->_M_impl._M_end_of_storage
84 : : - this->_M_impl._M_start);
85 : 0 : this->_M_impl._M_start = __tmp;
86 : 0 : this->_M_impl._M_finish = __tmp + __old_size;
87 : 0 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
88 : : }
89 : 0 : }
90 : :
91 : : template<typename _Tp, typename _Alloc>
92 : : typename vector<_Tp, _Alloc>::iterator
93 : : vector<_Tp, _Alloc>::
94 : : insert(iterator __position, const value_type& __x)
95 : : {
96 : : const size_type __n = __position - begin();
97 : : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
98 : : && __position == end())
99 : : {
100 : : this->_M_impl.construct(this->_M_impl._M_finish, __x);
101 : : ++this->_M_impl._M_finish;
102 : : }
103 : : else
104 : : {
105 : : #ifdef __GXX_EXPERIMENTAL_CXX0X__
106 : : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
107 : : {
108 : : _Tp __x_copy = __x;
109 : : _M_insert_aux(__position, std::move(__x_copy));
110 : : }
111 : : else
112 : : #endif
113 : : _M_insert_aux(__position, __x);
114 : : }
115 : : return iterator(this->_M_impl._M_start + __n);
116 : : }
117 : :
118 : : template<typename _Tp, typename _Alloc>
119 : : typename vector<_Tp, _Alloc>::iterator
120 : : vector<_Tp, _Alloc>::
121 : 0 : erase(iterator __position)
122 : : {
123 [ # # ][ # # ]: 0 : if (__position + 1 != end())
[ # # ]
124 : 0 : _GLIBCXX_MOVE3(__position + 1, end(), __position);
125 : 0 : --this->_M_impl._M_finish;
126 : 0 : this->_M_impl.destroy(this->_M_impl._M_finish);
127 : 0 : return __position;
128 : : }
129 : :
130 : : template<typename _Tp, typename _Alloc>
131 : : typename vector<_Tp, _Alloc>::iterator
132 : : vector<_Tp, _Alloc>::
133 : : erase(iterator __first, iterator __last)
134 : : {
135 : : if (__last != end())
136 : : _GLIBCXX_MOVE3(__last, end(), __first);
137 : : _M_erase_at_end(__first.base() + (end() - __last));
138 : : return __first;
139 : : }
140 : :
141 : : template<typename _Tp, typename _Alloc>
142 : : vector<_Tp, _Alloc>&
143 : : vector<_Tp, _Alloc>::
144 : 44 : operator=(const vector<_Tp, _Alloc>& __x)
145 : : {
146 [ + - ][ # # ]: 44 : if (&__x != this)
[ # # ][ # # ]
[ # # ]
147 : : {
148 : 44 : const size_type __xlen = __x.size();
149 [ + + ][ # # ]: 44 : if (__xlen > capacity())
[ # # ][ # # ]
[ # # ]
150 : : {
151 : : pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
152 : 123 : __x.end());
153 : 44 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
154 : : _M_get_Tp_allocator());
155 : 41 : _M_deallocate(this->_M_impl._M_start,
156 : : this->_M_impl._M_end_of_storage
157 : : - this->_M_impl._M_start);
158 : 41 : this->_M_impl._M_start = __tmp;
159 : 41 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
160 : : }
161 [ + - ][ # # ]: 3 : else if (size() >= __xlen)
[ # # ][ # # ]
[ # # ]
162 : : {
163 : 18 : std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
164 : : end(), _M_get_Tp_allocator());
165 : : }
166 : : else
167 : : {
168 : 0 : std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
169 : : this->_M_impl._M_start);
170 : 0 : std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
171 : : __x._M_impl._M_finish,
172 : : this->_M_impl._M_finish,
173 : : _M_get_Tp_allocator());
174 : : }
175 : 44 : this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
176 : : }
177 : 44 : return *this;
178 : : }
179 : :
180 : : template<typename _Tp, typename _Alloc>
181 : : void
182 : : vector<_Tp, _Alloc>::
183 : : _M_fill_assign(size_t __n, const value_type& __val)
184 : : {
185 : : if (__n > capacity())
186 : : {
187 : : vector __tmp(__n, __val, _M_get_Tp_allocator());
188 : : __tmp.swap(*this);
189 : : }
190 : : else if (__n > size())
191 : : {
192 : : std::fill(begin(), end(), __val);
193 : : std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
194 : : __n - size(), __val,
195 : : _M_get_Tp_allocator());
196 : : this->_M_impl._M_finish += __n - size();
197 : : }
198 : : else
199 : : _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
200 : : }
201 : :
202 : : template<typename _Tp, typename _Alloc>
203 : : template<typename _InputIterator>
204 : : void
205 : : vector<_Tp, _Alloc>::
206 : : _M_assign_aux(_InputIterator __first, _InputIterator __last,
207 : : std::input_iterator_tag)
208 : : {
209 : : pointer __cur(this->_M_impl._M_start);
210 : : for (; __first != __last && __cur != this->_M_impl._M_finish;
211 : : ++__cur, ++__first)
212 : : *__cur = *__first;
213 : : if (__first == __last)
214 : : _M_erase_at_end(__cur);
215 : : else
216 : : insert(end(), __first, __last);
217 : : }
218 : :
219 : : template<typename _Tp, typename _Alloc>
220 : : template<typename _ForwardIterator>
221 : : void
222 : : vector<_Tp, _Alloc>::
223 : : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
224 : : std::forward_iterator_tag)
225 : : {
226 : : const size_type __len = std::distance(__first, __last);
227 : :
228 : : if (__len > capacity())
229 : : {
230 : : pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
231 : : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
232 : : _M_get_Tp_allocator());
233 : : _M_deallocate(this->_M_impl._M_start,
234 : : this->_M_impl._M_end_of_storage
235 : : - this->_M_impl._M_start);
236 : : this->_M_impl._M_start = __tmp;
237 : : this->_M_impl._M_finish = this->_M_impl._M_start + __len;
238 : : this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
239 : : }
240 : : else if (size() >= __len)
241 : : _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
242 : : else
243 : : {
244 : : _ForwardIterator __mid = __first;
245 : : std::advance(__mid, size());
246 : : std::copy(__first, __mid, this->_M_impl._M_start);
247 : : this->_M_impl._M_finish =
248 : : std::__uninitialized_copy_a(__mid, __last,
249 : : this->_M_impl._M_finish,
250 : : _M_get_Tp_allocator());
251 : : }
252 : : }
253 : :
254 : : #ifdef __GXX_EXPERIMENTAL_CXX0X__
255 : : template<typename _Tp, typename _Alloc>
256 : : template<typename... _Args>
257 : : typename vector<_Tp, _Alloc>::iterator
258 : : vector<_Tp, _Alloc>::
259 : : emplace(iterator __position, _Args&&... __args)
260 : : {
261 : : const size_type __n = __position - begin();
262 : : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
263 : : && __position == end())
264 : : {
265 : : this->_M_impl.construct(this->_M_impl._M_finish,
266 : : std::forward<_Args>(__args)...);
267 : : ++this->_M_impl._M_finish;
268 : : }
269 : : else
270 : : _M_insert_aux(__position, std::forward<_Args>(__args)...);
271 : : return iterator(this->_M_impl._M_start + __n);
272 : : }
273 : :
274 : : template<typename _Tp, typename _Alloc>
275 : : template<typename... _Args>
276 : : void
277 : : vector<_Tp, _Alloc>::
278 : : _M_insert_aux(iterator __position, _Args&&... __args)
279 : : #else
280 : : template<typename _Tp, typename _Alloc>
281 : : void
282 : : vector<_Tp, _Alloc>::
283 : 14732 : _M_insert_aux(iterator __position, const _Tp& __x)
284 : : #endif
285 : : {
286 [ - + ][ - + ]: 14732 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
[ - + ][ - + ]
[ - + ][ # # ]
[ - + ]
287 : : {
288 : 0 : this->_M_impl.construct(this->_M_impl._M_finish,
289 : : _GLIBCXX_MOVE(*(this->_M_impl._M_finish
290 : : - 1)));
291 : 0 : ++this->_M_impl._M_finish;
292 : : #ifndef __GXX_EXPERIMENTAL_CXX0X__
293 : 0 : _Tp __x_copy = __x;
294 : : #endif
295 : 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
296 : : this->_M_impl._M_finish - 2,
297 : : this->_M_impl._M_finish - 1);
298 : : #ifndef __GXX_EXPERIMENTAL_CXX0X__
299 : 0 : *__position = __x_copy;
300 : : #else
301 : : *__position = _Tp(std::forward<_Args>(__args)...);
302 : : #endif
303 : : }
304 : : else
305 : : {
306 : : const size_type __len =
307 : 29464 : _M_check_len(size_type(1), "vector::_M_insert_aux");
308 : 21026 : pointer __new_start(this->_M_allocate(__len));
309 : 14732 : pointer __new_finish(__new_start);
310 : : try
311 : : {
312 : : #ifdef __GXX_EXPERIMENTAL_CXX0X__
313 : : this->_M_impl.construct(__new_start + (__position - begin()),
314 : : std::forward<_Args>(__args)...);
315 : : #endif
316 : 14539 : __new_finish =
317 : : std::__uninitialized_move_a(this->_M_impl._M_start,
318 : : __position.base(), __new_start,
319 : : _M_get_Tp_allocator());
320 : : #ifndef __GXX_EXPERIMENTAL_CXX0X__
321 : 14732 : this->_M_impl.construct(__new_finish, __x);
322 : : #endif
323 : 14732 : ++__new_finish;
324 : 14564 : __new_finish =
325 : : std::__uninitialized_move_a(__position.base(),
326 : : this->_M_impl._M_finish,
327 : : __new_finish,
328 : : _M_get_Tp_allocator());
329 : : }
330 : 0 : catch(...)
331 : : {
332 : 0 : std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
333 : 0 : _M_deallocate(__new_start, __len);
334 : 0 : __throw_exception_again;
335 : : }
336 : 15563 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
337 : : _M_get_Tp_allocator());
338 : 14732 : _M_deallocate(this->_M_impl._M_start,
339 : : this->_M_impl._M_end_of_storage
340 : : - this->_M_impl._M_start);
341 : 14732 : this->_M_impl._M_start = __new_start;
342 : 14732 : this->_M_impl._M_finish = __new_finish;
343 : 14732 : this->_M_impl._M_end_of_storage = __new_start + __len;
344 : : }
345 : 14732 : }
346 : :
347 : : template<typename _Tp, typename _Alloc>
348 : : void
349 : : vector<_Tp, _Alloc>::
350 : 0 : _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
351 : : {
352 [ # # ]: 0 : if (__n != 0)
353 : : {
354 : : #ifdef __GXX_EXPERIMENTAL_CXX0X__
355 : : value_type __x_copy = __x;
356 : : #endif
357 [ # # ]: 0 : if (size_type(this->_M_impl._M_end_of_storage
358 : : - this->_M_impl._M_finish) >= __n)
359 : : {
360 : : #ifndef __GXX_EXPERIMENTAL_CXX0X__
361 : 0 : value_type __x_copy = __x;
362 : : #endif
363 : 0 : const size_type __elems_after = end() - __position;
364 : 0 : pointer __old_finish(this->_M_impl._M_finish);
365 [ # # ]: 0 : if (__elems_after > __n)
366 : : {
367 : 0 : std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
368 : : this->_M_impl._M_finish,
369 : : this->_M_impl._M_finish,
370 : : _M_get_Tp_allocator());
371 : 0 : this->_M_impl._M_finish += __n;
372 : 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
373 : : __old_finish - __n, __old_finish);
374 : 0 : std::fill(__position.base(), __position.base() + __n,
375 : : __x_copy);
376 : : }
377 : : else
378 : : {
379 : 0 : std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
380 : : __n - __elems_after,
381 : : __x_copy,
382 : : _M_get_Tp_allocator());
383 : 0 : this->_M_impl._M_finish += __n - __elems_after;
384 : 0 : std::__uninitialized_move_a(__position.base(), __old_finish,
385 : : this->_M_impl._M_finish,
386 : : _M_get_Tp_allocator());
387 : 0 : this->_M_impl._M_finish += __elems_after;
388 : 0 : std::fill(__position.base(), __old_finish, __x_copy);
389 : : }
390 : : }
391 : : else
392 : : {
393 : : const size_type __len =
394 : 0 : _M_check_len(__n, "vector::_M_fill_insert");
395 : 0 : pointer __new_start(this->_M_allocate(__len));
396 : 0 : pointer __new_finish(__new_start);
397 : : try
398 : : {
399 : 0 : __new_finish =
400 : : std::__uninitialized_move_a(this->_M_impl._M_start,
401 : : __position.base(),
402 : : __new_start,
403 : : _M_get_Tp_allocator());
404 : : #ifdef __GXX_EXPERIMENTAL_CXX0X__
405 : : std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy,
406 : : #else
407 : 0 : std::__uninitialized_fill_n_a(__new_finish, __n, __x,
408 : : #endif
409 : : _M_get_Tp_allocator());
410 : 0 : __new_finish += __n;
411 : 0 : __new_finish =
412 : : std::__uninitialized_move_a(__position.base(),
413 : : this->_M_impl._M_finish,
414 : : __new_finish,
415 : : _M_get_Tp_allocator());
416 : : }
417 : 0 : catch(...)
418 : : {
419 : 0 : std::_Destroy(__new_start, __new_finish,
420 : : _M_get_Tp_allocator());
421 : 0 : _M_deallocate(__new_start, __len);
422 : 0 : __throw_exception_again;
423 : : }
424 : 0 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
425 : : _M_get_Tp_allocator());
426 : 0 : _M_deallocate(this->_M_impl._M_start,
427 : : this->_M_impl._M_end_of_storage
428 : : - this->_M_impl._M_start);
429 : 0 : this->_M_impl._M_start = __new_start;
430 : 0 : this->_M_impl._M_finish = __new_finish;
431 : 0 : this->_M_impl._M_end_of_storage = __new_start + __len;
432 : : }
433 : : }
434 : 0 : }
435 : :
436 : : template<typename _Tp, typename _Alloc>
437 : : template<typename _InputIterator>
438 : : void
439 : : vector<_Tp, _Alloc>::
440 : : _M_range_insert(iterator __pos, _InputIterator __first,
441 : : _InputIterator __last, std::input_iterator_tag)
442 : : {
443 : : for (; __first != __last; ++__first)
444 : : {
445 : : __pos = insert(__pos, *__first);
446 : : ++__pos;
447 : : }
448 : : }
449 : :
450 : : template<typename _Tp, typename _Alloc>
451 : : template<typename _ForwardIterator>
452 : : void
453 : : vector<_Tp, _Alloc>::
454 : : _M_range_insert(iterator __position, _ForwardIterator __first,
455 : : _ForwardIterator __last, std::forward_iterator_tag)
456 : : {
457 : : if (__first != __last)
458 : : {
459 : : const size_type __n = std::distance(__first, __last);
460 : : if (size_type(this->_M_impl._M_end_of_storage
461 : : - this->_M_impl._M_finish) >= __n)
462 : : {
463 : : const size_type __elems_after = end() - __position;
464 : : pointer __old_finish(this->_M_impl._M_finish);
465 : : if (__elems_after > __n)
466 : : {
467 : : std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
468 : : this->_M_impl._M_finish,
469 : : this->_M_impl._M_finish,
470 : : _M_get_Tp_allocator());
471 : : this->_M_impl._M_finish += __n;
472 : : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
473 : : __old_finish - __n, __old_finish);
474 : : std::copy(__first, __last, __position);
475 : : }
476 : : else
477 : : {
478 : : _ForwardIterator __mid = __first;
479 : : std::advance(__mid, __elems_after);
480 : : std::__uninitialized_copy_a(__mid, __last,
481 : : this->_M_impl._M_finish,
482 : : _M_get_Tp_allocator());
483 : : this->_M_impl._M_finish += __n - __elems_after;
484 : : std::__uninitialized_move_a(__position.base(),
485 : : __old_finish,
486 : : this->_M_impl._M_finish,
487 : : _M_get_Tp_allocator());
488 : : this->_M_impl._M_finish += __elems_after;
489 : : std::copy(__first, __mid, __position);
490 : : }
491 : : }
492 : : else
493 : : {
494 : : const size_type __len =
495 : : _M_check_len(__n, "vector::_M_range_insert");
496 : : pointer __new_start(this->_M_allocate(__len));
497 : : pointer __new_finish(__new_start);
498 : : try
499 : : {
500 : : __new_finish =
501 : : std::__uninitialized_move_a(this->_M_impl._M_start,
502 : : __position.base(),
503 : : __new_start,
504 : : _M_get_Tp_allocator());
505 : : __new_finish =
506 : : std::__uninitialized_copy_a(__first, __last,
507 : : __new_finish,
508 : : _M_get_Tp_allocator());
509 : : __new_finish =
510 : : std::__uninitialized_move_a(__position.base(),
511 : : this->_M_impl._M_finish,
512 : : __new_finish,
513 : : _M_get_Tp_allocator());
514 : : }
515 : : catch(...)
516 : : {
517 : : std::_Destroy(__new_start, __new_finish,
518 : : _M_get_Tp_allocator());
519 : : _M_deallocate(__new_start, __len);
520 : : __throw_exception_again;
521 : : }
522 : : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
523 : : _M_get_Tp_allocator());
524 : : _M_deallocate(this->_M_impl._M_start,
525 : : this->_M_impl._M_end_of_storage
526 : : - this->_M_impl._M_start);
527 : : this->_M_impl._M_start = __new_start;
528 : : this->_M_impl._M_finish = __new_finish;
529 : : this->_M_impl._M_end_of_storage = __new_start + __len;
530 : : }
531 : : }
532 : : }
533 : :
534 : :
535 : : // vector<bool>
536 : :
537 : : template<typename _Alloc>
538 : : void
539 : : vector<bool, _Alloc>::
540 : : reserve(size_type __n)
541 : : {
542 : : if (__n > this->max_size())
543 : : __throw_length_error(__N("vector::reserve"));
544 : : if (this->capacity() < __n)
545 : : {
546 : : _Bit_type* __q = this->_M_allocate(__n);
547 : : this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
548 : : iterator(__q, 0));
549 : : this->_M_deallocate();
550 : : this->_M_impl._M_start = iterator(__q, 0);
551 : : this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1)
552 : : / int(_S_word_bit));
553 : : }
554 : : }
555 : :
556 : : template<typename _Alloc>
557 : : void
558 : : vector<bool, _Alloc>::
559 : : _M_fill_insert(iterator __position, size_type __n, bool __x)
560 : : {
561 : : if (__n == 0)
562 : : return;
563 : : if (capacity() - size() >= __n)
564 : : {
565 : : std::copy_backward(__position, end(),
566 : : this->_M_impl._M_finish + difference_type(__n));
567 : : std::fill(__position, __position + difference_type(__n), __x);
568 : : this->_M_impl._M_finish += difference_type(__n);
569 : : }
570 : : else
571 : : {
572 : : const size_type __len =
573 : : _M_check_len(__n, "vector<bool>::_M_fill_insert");
574 : : _Bit_type * __q = this->_M_allocate(__len);
575 : : iterator __i = _M_copy_aligned(begin(), __position,
576 : : iterator(__q, 0));
577 : : std::fill(__i, __i + difference_type(__n), __x);
578 : : this->_M_impl._M_finish = std::copy(__position, end(),
579 : : __i + difference_type(__n));
580 : : this->_M_deallocate();
581 : : this->_M_impl._M_end_of_storage = (__q + ((__len
582 : : + int(_S_word_bit) - 1)
583 : : / int(_S_word_bit)));
584 : : this->_M_impl._M_start = iterator(__q, 0);
585 : : }
586 : : }
587 : :
588 : : template<typename _Alloc>
589 : : template<typename _ForwardIterator>
590 : : void
591 : : vector<bool, _Alloc>::
592 : : _M_insert_range(iterator __position, _ForwardIterator __first,
593 : : _ForwardIterator __last, std::forward_iterator_tag)
594 : : {
595 : : if (__first != __last)
596 : : {
597 : : size_type __n = std::distance(__first, __last);
598 : : if (capacity() - size() >= __n)
599 : : {
600 : : std::copy_backward(__position, end(),
601 : : this->_M_impl._M_finish
602 : : + difference_type(__n));
603 : : std::copy(__first, __last, __position);
604 : : this->_M_impl._M_finish += difference_type(__n);
605 : : }
606 : : else
607 : : {
608 : : const size_type __len =
609 : : _M_check_len(__n, "vector<bool>::_M_insert_range");
610 : : _Bit_type * __q = this->_M_allocate(__len);
611 : : iterator __i = _M_copy_aligned(begin(), __position,
612 : : iterator(__q, 0));
613 : : __i = std::copy(__first, __last, __i);
614 : : this->_M_impl._M_finish = std::copy(__position, end(), __i);
615 : : this->_M_deallocate();
616 : : this->_M_impl._M_end_of_storage = (__q
617 : : + ((__len
618 : : + int(_S_word_bit) - 1)
619 : : / int(_S_word_bit)));
620 : : this->_M_impl._M_start = iterator(__q, 0);
621 : : }
622 : : }
623 : : }
624 : :
625 : : template<typename _Alloc>
626 : : void
627 : : vector<bool, _Alloc>::
628 : 11 : _M_insert_aux(iterator __position, bool __x)
629 : : {
630 [ - + ]: 11 : if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
631 : : {
632 : 0 : std::copy_backward(__position, this->_M_impl._M_finish,
633 : : this->_M_impl._M_finish + 1);
634 : 0 : *__position = __x;
635 : 0 : ++this->_M_impl._M_finish;
636 : : }
637 : : else
638 : : {
639 : : const size_type __len =
640 : 22 : _M_check_len(size_type(1), "vector<bool>::_M_insert_aux");
641 : 22 : _Bit_type * __q = this->_M_allocate(__len);
642 : : iterator __i = _M_copy_aligned(begin(), __position,
643 : 33 : iterator(__q, 0));
644 : 33 : *__i++ = __x;
645 : 22 : this->_M_impl._M_finish = std::copy(__position, end(), __i);
646 : 11 : this->_M_deallocate();
647 : 11 : this->_M_impl._M_end_of_storage = (__q + ((__len
648 : : + int(_S_word_bit) - 1)
649 : : / int(_S_word_bit)));
650 : 11 : this->_M_impl._M_start = iterator(__q, 0);
651 : : }
652 : 11 : }
653 : :
654 : : _GLIBCXX_END_NESTED_NAMESPACE
655 : :
656 : : #endif /* _VECTOR_TCC */
|