]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/vector.tcc
* many: Replace uses of __GXX_EXPERIMENTAL_CXX0X__ with __cplusplus.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / vector.tcc
1 // Vector implementation (out of line) -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /*
27 *
28 * Copyright (c) 1994
29 * Hewlett-Packard Company
30 *
31 * Permission to use, copy, modify, distribute and sell this software
32 * and its documentation for any purpose is hereby granted without fee,
33 * provided that the above copyright notice appear in all copies and
34 * that both that copyright notice and this permission notice appear
35 * in supporting documentation. Hewlett-Packard Company makes no
36 * representations about the suitability of this software for any
37 * purpose. It is provided "as is" without express or implied warranty.
38 *
39 *
40 * Copyright (c) 1996
41 * Silicon Graphics Computer Systems, Inc.
42 *
43 * Permission to use, copy, modify, distribute and sell this software
44 * and its documentation for any purpose is hereby granted without fee,
45 * provided that the above copyright notice appear in all copies and
46 * that both that copyright notice and this permission notice appear
47 * in supporting documentation. Silicon Graphics makes no
48 * representations about the suitability of this software for any
49 * purpose. It is provided "as is" without express or implied warranty.
50 */
51
52 /** @file bits/vector.tcc
53 * This is an internal header file, included by other library headers.
54 * Do not attempt to use it directly. @headername{vector}
55 */
56
57 #ifndef _VECTOR_TCC
58 #define _VECTOR_TCC 1
59
60 namespace std _GLIBCXX_VISIBILITY(default)
61 {
62 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63
64 template<typename _Tp, typename _Alloc>
65 void
66 vector<_Tp, _Alloc>::
67 reserve(size_type __n)
68 {
69 if (__n > this->max_size())
70 __throw_length_error(__N("vector::reserve"));
71 if (this->capacity() < __n)
72 {
73 const size_type __old_size = size();
74 pointer __tmp = _M_allocate_and_copy(__n,
75 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
76 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
77 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
78 _M_get_Tp_allocator());
79 _M_deallocate(this->_M_impl._M_start,
80 this->_M_impl._M_end_of_storage
81 - this->_M_impl._M_start);
82 this->_M_impl._M_start = __tmp;
83 this->_M_impl._M_finish = __tmp + __old_size;
84 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
85 }
86 }
87
88 #if __cplusplus >= 201103L
89 template<typename _Tp, typename _Alloc>
90 template<typename... _Args>
91 void
92 vector<_Tp, _Alloc>::
93 emplace_back(_Args&&... __args)
94 {
95 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
96 {
97 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
98 std::forward<_Args>(__args)...);
99 ++this->_M_impl._M_finish;
100 }
101 else
102 _M_emplace_back_aux(std::forward<_Args>(__args)...);
103 }
104 #endif
105
106 template<typename _Tp, typename _Alloc>
107 typename vector<_Tp, _Alloc>::iterator
108 vector<_Tp, _Alloc>::
109 insert(iterator __position, const value_type& __x)
110 {
111 const size_type __n = __position - begin();
112 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
113 && __position == end())
114 {
115 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x);
116 ++this->_M_impl._M_finish;
117 }
118 else
119 {
120 #if __cplusplus >= 201103L
121 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
122 {
123 _Tp __x_copy = __x;
124 _M_insert_aux(__position, std::move(__x_copy));
125 }
126 else
127 #endif
128 _M_insert_aux(__position, __x);
129 }
130 return iterator(this->_M_impl._M_start + __n);
131 }
132
133 template<typename _Tp, typename _Alloc>
134 typename vector<_Tp, _Alloc>::iterator
135 vector<_Tp, _Alloc>::
136 erase(iterator __position)
137 {
138 if (__position + 1 != end())
139 _GLIBCXX_MOVE3(__position + 1, end(), __position);
140 --this->_M_impl._M_finish;
141 _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
142 return __position;
143 }
144
145 template<typename _Tp, typename _Alloc>
146 typename vector<_Tp, _Alloc>::iterator
147 vector<_Tp, _Alloc>::
148 erase(iterator __first, iterator __last)
149 {
150 if (__first != __last)
151 {
152 if (__last != end())
153 _GLIBCXX_MOVE3(__last, end(), __first);
154 _M_erase_at_end(__first.base() + (end() - __last));
155 }
156 return __first;
157 }
158
159 template<typename _Tp, typename _Alloc>
160 vector<_Tp, _Alloc>&
161 vector<_Tp, _Alloc>::
162 operator=(const vector<_Tp, _Alloc>& __x)
163 {
164 if (&__x != this)
165 {
166 #if __cplusplus >= 201103L
167 if (_Alloc_traits::_S_propagate_on_copy_assign())
168 {
169 if (!_Alloc_traits::_S_always_equal()
170 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
171 {
172 // replacement allocator cannot free existing storage
173 this->clear();
174 _M_deallocate(this->_M_impl._M_start,
175 this->_M_impl._M_end_of_storage
176 - this->_M_impl._M_start);
177 }
178 std::__alloc_on_copy(_M_get_Tp_allocator(),
179 __x._M_get_Tp_allocator());
180 }
181 #endif
182 const size_type __xlen = __x.size();
183 if (__xlen > capacity())
184 {
185 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
186 __x.end());
187 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
188 _M_get_Tp_allocator());
189 _M_deallocate(this->_M_impl._M_start,
190 this->_M_impl._M_end_of_storage
191 - this->_M_impl._M_start);
192 this->_M_impl._M_start = __tmp;
193 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
194 }
195 else if (size() >= __xlen)
196 {
197 std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
198 end(), _M_get_Tp_allocator());
199 }
200 else
201 {
202 std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
203 this->_M_impl._M_start);
204 std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
205 __x._M_impl._M_finish,
206 this->_M_impl._M_finish,
207 _M_get_Tp_allocator());
208 }
209 this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
210 }
211 return *this;
212 }
213
214 template<typename _Tp, typename _Alloc>
215 void
216 vector<_Tp, _Alloc>::
217 _M_fill_assign(size_t __n, const value_type& __val)
218 {
219 if (__n > capacity())
220 {
221 vector __tmp(__n, __val, _M_get_Tp_allocator());
222 __tmp.swap(*this);
223 }
224 else if (__n > size())
225 {
226 std::fill(begin(), end(), __val);
227 std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
228 __n - size(), __val,
229 _M_get_Tp_allocator());
230 this->_M_impl._M_finish += __n - size();
231 }
232 else
233 _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
234 }
235
236 template<typename _Tp, typename _Alloc>
237 template<typename _InputIterator>
238 void
239 vector<_Tp, _Alloc>::
240 _M_assign_aux(_InputIterator __first, _InputIterator __last,
241 std::input_iterator_tag)
242 {
243 pointer __cur(this->_M_impl._M_start);
244 for (; __first != __last && __cur != this->_M_impl._M_finish;
245 ++__cur, ++__first)
246 *__cur = *__first;
247 if (__first == __last)
248 _M_erase_at_end(__cur);
249 else
250 insert(end(), __first, __last);
251 }
252
253 template<typename _Tp, typename _Alloc>
254 template<typename _ForwardIterator>
255 void
256 vector<_Tp, _Alloc>::
257 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
258 std::forward_iterator_tag)
259 {
260 const size_type __len = std::distance(__first, __last);
261
262 if (__len > capacity())
263 {
264 pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
265 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
266 _M_get_Tp_allocator());
267 _M_deallocate(this->_M_impl._M_start,
268 this->_M_impl._M_end_of_storage
269 - this->_M_impl._M_start);
270 this->_M_impl._M_start = __tmp;
271 this->_M_impl._M_finish = this->_M_impl._M_start + __len;
272 this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
273 }
274 else if (size() >= __len)
275 _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
276 else
277 {
278 _ForwardIterator __mid = __first;
279 std::advance(__mid, size());
280 std::copy(__first, __mid, this->_M_impl._M_start);
281 this->_M_impl._M_finish =
282 std::__uninitialized_copy_a(__mid, __last,
283 this->_M_impl._M_finish,
284 _M_get_Tp_allocator());
285 }
286 }
287
288 #if __cplusplus >= 201103L
289 template<typename _Tp, typename _Alloc>
290 template<typename... _Args>
291 typename vector<_Tp, _Alloc>::iterator
292 vector<_Tp, _Alloc>::
293 emplace(iterator __position, _Args&&... __args)
294 {
295 const size_type __n = __position - begin();
296 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
297 && __position == end())
298 {
299 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
300 std::forward<_Args>(__args)...);
301 ++this->_M_impl._M_finish;
302 }
303 else
304 _M_insert_aux(__position, std::forward<_Args>(__args)...);
305 return iterator(this->_M_impl._M_start + __n);
306 }
307
308 template<typename _Tp, typename _Alloc>
309 template<typename... _Args>
310 void
311 vector<_Tp, _Alloc>::
312 _M_insert_aux(iterator __position, _Args&&... __args)
313 #else
314 template<typename _Tp, typename _Alloc>
315 void
316 vector<_Tp, _Alloc>::
317 _M_insert_aux(iterator __position, const _Tp& __x)
318 #endif
319 {
320 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
321 {
322 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
323 _GLIBCXX_MOVE(*(this->_M_impl._M_finish
324 - 1)));
325 ++this->_M_impl._M_finish;
326 #if __cplusplus < 201103L
327 _Tp __x_copy = __x;
328 #endif
329 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
330 this->_M_impl._M_finish - 2,
331 this->_M_impl._M_finish - 1);
332 #if __cplusplus < 201103L
333 *__position = __x_copy;
334 #else
335 *__position = _Tp(std::forward<_Args>(__args)...);
336 #endif
337 }
338 else
339 {
340 const size_type __len =
341 _M_check_len(size_type(1), "vector::_M_insert_aux");
342 const size_type __elems_before = __position - begin();
343 pointer __new_start(this->_M_allocate(__len));
344 pointer __new_finish(__new_start);
345 __try
346 {
347 // The order of the three operations is dictated by the C++0x
348 // case, where the moves could alter a new element belonging
349 // to the existing vector. This is an issue only for callers
350 // taking the element by const lvalue ref (see 23.1/13).
351 _Alloc_traits::construct(this->_M_impl,
352 __new_start + __elems_before,
353 #if __cplusplus >= 201103L
354 std::forward<_Args>(__args)...);
355 #else
356 __x);
357 #endif
358 __new_finish = 0;
359
360 __new_finish
361 = std::__uninitialized_move_if_noexcept_a
362 (this->_M_impl._M_start, __position.base(),
363 __new_start, _M_get_Tp_allocator());
364
365 ++__new_finish;
366
367 __new_finish
368 = std::__uninitialized_move_if_noexcept_a
369 (__position.base(), this->_M_impl._M_finish,
370 __new_finish, _M_get_Tp_allocator());
371 }
372 __catch(...)
373 {
374 if (!__new_finish)
375 _Alloc_traits::destroy(this->_M_impl,
376 __new_start + __elems_before);
377 else
378 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
379 _M_deallocate(__new_start, __len);
380 __throw_exception_again;
381 }
382 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
383 _M_get_Tp_allocator());
384 _M_deallocate(this->_M_impl._M_start,
385 this->_M_impl._M_end_of_storage
386 - this->_M_impl._M_start);
387 this->_M_impl._M_start = __new_start;
388 this->_M_impl._M_finish = __new_finish;
389 this->_M_impl._M_end_of_storage = __new_start + __len;
390 }
391 }
392
393 #if __cplusplus >= 201103L
394 template<typename _Tp, typename _Alloc>
395 template<typename... _Args>
396 void
397 vector<_Tp, _Alloc>::
398 _M_emplace_back_aux(_Args&&... __args)
399 {
400 const size_type __len =
401 _M_check_len(size_type(1), "vector::_M_emplace_back_aux");
402 pointer __new_start(this->_M_allocate(__len));
403 pointer __new_finish(__new_start);
404 __try
405 {
406 _Alloc_traits::construct(this->_M_impl, __new_start + size(),
407 std::forward<_Args>(__args)...);
408 __new_finish = 0;
409
410 __new_finish
411 = std::__uninitialized_move_if_noexcept_a
412 (this->_M_impl._M_start, this->_M_impl._M_finish,
413 __new_start, _M_get_Tp_allocator());
414
415 ++__new_finish;
416 }
417 __catch(...)
418 {
419 if (!__new_finish)
420 _Alloc_traits::destroy(this->_M_impl, __new_start + size());
421 else
422 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
423 _M_deallocate(__new_start, __len);
424 __throw_exception_again;
425 }
426 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
427 _M_get_Tp_allocator());
428 _M_deallocate(this->_M_impl._M_start,
429 this->_M_impl._M_end_of_storage
430 - this->_M_impl._M_start);
431 this->_M_impl._M_start = __new_start;
432 this->_M_impl._M_finish = __new_finish;
433 this->_M_impl._M_end_of_storage = __new_start + __len;
434 }
435 #endif
436
437 template<typename _Tp, typename _Alloc>
438 void
439 vector<_Tp, _Alloc>::
440 _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
441 {
442 if (__n != 0)
443 {
444 if (size_type(this->_M_impl._M_end_of_storage
445 - this->_M_impl._M_finish) >= __n)
446 {
447 value_type __x_copy = __x;
448 const size_type __elems_after = end() - __position;
449 pointer __old_finish(this->_M_impl._M_finish);
450 if (__elems_after > __n)
451 {
452 std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
453 this->_M_impl._M_finish,
454 this->_M_impl._M_finish,
455 _M_get_Tp_allocator());
456 this->_M_impl._M_finish += __n;
457 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
458 __old_finish - __n, __old_finish);
459 std::fill(__position.base(), __position.base() + __n,
460 __x_copy);
461 }
462 else
463 {
464 std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
465 __n - __elems_after,
466 __x_copy,
467 _M_get_Tp_allocator());
468 this->_M_impl._M_finish += __n - __elems_after;
469 std::__uninitialized_move_a(__position.base(), __old_finish,
470 this->_M_impl._M_finish,
471 _M_get_Tp_allocator());
472 this->_M_impl._M_finish += __elems_after;
473 std::fill(__position.base(), __old_finish, __x_copy);
474 }
475 }
476 else
477 {
478 const size_type __len =
479 _M_check_len(__n, "vector::_M_fill_insert");
480 const size_type __elems_before = __position - begin();
481 pointer __new_start(this->_M_allocate(__len));
482 pointer __new_finish(__new_start);
483 __try
484 {
485 // See _M_insert_aux above.
486 std::__uninitialized_fill_n_a(__new_start + __elems_before,
487 __n, __x,
488 _M_get_Tp_allocator());
489 __new_finish = 0;
490
491 __new_finish
492 = std::__uninitialized_move_if_noexcept_a
493 (this->_M_impl._M_start, __position.base(),
494 __new_start, _M_get_Tp_allocator());
495
496 __new_finish += __n;
497
498 __new_finish
499 = std::__uninitialized_move_if_noexcept_a
500 (__position.base(), this->_M_impl._M_finish,
501 __new_finish, _M_get_Tp_allocator());
502 }
503 __catch(...)
504 {
505 if (!__new_finish)
506 std::_Destroy(__new_start + __elems_before,
507 __new_start + __elems_before + __n,
508 _M_get_Tp_allocator());
509 else
510 std::_Destroy(__new_start, __new_finish,
511 _M_get_Tp_allocator());
512 _M_deallocate(__new_start, __len);
513 __throw_exception_again;
514 }
515 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
516 _M_get_Tp_allocator());
517 _M_deallocate(this->_M_impl._M_start,
518 this->_M_impl._M_end_of_storage
519 - this->_M_impl._M_start);
520 this->_M_impl._M_start = __new_start;
521 this->_M_impl._M_finish = __new_finish;
522 this->_M_impl._M_end_of_storage = __new_start + __len;
523 }
524 }
525 }
526
527 #if __cplusplus >= 201103L
528 template<typename _Tp, typename _Alloc>
529 void
530 vector<_Tp, _Alloc>::
531 _M_default_append(size_type __n)
532 {
533 if (__n != 0)
534 {
535 if (size_type(this->_M_impl._M_end_of_storage
536 - this->_M_impl._M_finish) >= __n)
537 {
538 std::__uninitialized_default_n_a(this->_M_impl._M_finish,
539 __n, _M_get_Tp_allocator());
540 this->_M_impl._M_finish += __n;
541 }
542 else
543 {
544 const size_type __len =
545 _M_check_len(__n, "vector::_M_default_append");
546 const size_type __old_size = this->size();
547 pointer __new_start(this->_M_allocate(__len));
548 pointer __new_finish(__new_start);
549 __try
550 {
551 __new_finish
552 = std::__uninitialized_move_if_noexcept_a
553 (this->_M_impl._M_start, this->_M_impl._M_finish,
554 __new_start, _M_get_Tp_allocator());
555 std::__uninitialized_default_n_a(__new_finish, __n,
556 _M_get_Tp_allocator());
557 __new_finish += __n;
558 }
559 __catch(...)
560 {
561 std::_Destroy(__new_start, __new_finish,
562 _M_get_Tp_allocator());
563 _M_deallocate(__new_start, __len);
564 __throw_exception_again;
565 }
566 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
567 _M_get_Tp_allocator());
568 _M_deallocate(this->_M_impl._M_start,
569 this->_M_impl._M_end_of_storage
570 - this->_M_impl._M_start);
571 this->_M_impl._M_start = __new_start;
572 this->_M_impl._M_finish = __new_finish;
573 this->_M_impl._M_end_of_storage = __new_start + __len;
574 }
575 }
576 }
577
578 template<typename _Tp, typename _Alloc>
579 bool
580 vector<_Tp, _Alloc>::
581 _M_shrink_to_fit()
582 {
583 if (capacity() == size())
584 return false;
585 return std::__shrink_to_fit_aux<vector>::_S_do_it(*this);
586 }
587 #endif
588
589 template<typename _Tp, typename _Alloc>
590 template<typename _InputIterator>
591 void
592 vector<_Tp, _Alloc>::
593 _M_range_insert(iterator __pos, _InputIterator __first,
594 _InputIterator __last, std::input_iterator_tag)
595 {
596 for (; __first != __last; ++__first)
597 {
598 __pos = insert(__pos, *__first);
599 ++__pos;
600 }
601 }
602
603 template<typename _Tp, typename _Alloc>
604 template<typename _ForwardIterator>
605 void
606 vector<_Tp, _Alloc>::
607 _M_range_insert(iterator __position, _ForwardIterator __first,
608 _ForwardIterator __last, std::forward_iterator_tag)
609 {
610 if (__first != __last)
611 {
612 const size_type __n = std::distance(__first, __last);
613 if (size_type(this->_M_impl._M_end_of_storage
614 - this->_M_impl._M_finish) >= __n)
615 {
616 const size_type __elems_after = end() - __position;
617 pointer __old_finish(this->_M_impl._M_finish);
618 if (__elems_after > __n)
619 {
620 std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
621 this->_M_impl._M_finish,
622 this->_M_impl._M_finish,
623 _M_get_Tp_allocator());
624 this->_M_impl._M_finish += __n;
625 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
626 __old_finish - __n, __old_finish);
627 std::copy(__first, __last, __position);
628 }
629 else
630 {
631 _ForwardIterator __mid = __first;
632 std::advance(__mid, __elems_after);
633 std::__uninitialized_copy_a(__mid, __last,
634 this->_M_impl._M_finish,
635 _M_get_Tp_allocator());
636 this->_M_impl._M_finish += __n - __elems_after;
637 std::__uninitialized_move_a(__position.base(),
638 __old_finish,
639 this->_M_impl._M_finish,
640 _M_get_Tp_allocator());
641 this->_M_impl._M_finish += __elems_after;
642 std::copy(__first, __mid, __position);
643 }
644 }
645 else
646 {
647 const size_type __len =
648 _M_check_len(__n, "vector::_M_range_insert");
649 pointer __new_start(this->_M_allocate(__len));
650 pointer __new_finish(__new_start);
651 __try
652 {
653 __new_finish
654 = std::__uninitialized_move_if_noexcept_a
655 (this->_M_impl._M_start, __position.base(),
656 __new_start, _M_get_Tp_allocator());
657 __new_finish
658 = std::__uninitialized_copy_a(__first, __last,
659 __new_finish,
660 _M_get_Tp_allocator());
661 __new_finish
662 = std::__uninitialized_move_if_noexcept_a
663 (__position.base(), this->_M_impl._M_finish,
664 __new_finish, _M_get_Tp_allocator());
665 }
666 __catch(...)
667 {
668 std::_Destroy(__new_start, __new_finish,
669 _M_get_Tp_allocator());
670 _M_deallocate(__new_start, __len);
671 __throw_exception_again;
672 }
673 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
674 _M_get_Tp_allocator());
675 _M_deallocate(this->_M_impl._M_start,
676 this->_M_impl._M_end_of_storage
677 - this->_M_impl._M_start);
678 this->_M_impl._M_start = __new_start;
679 this->_M_impl._M_finish = __new_finish;
680 this->_M_impl._M_end_of_storage = __new_start + __len;
681 }
682 }
683 }
684
685
686 // vector<bool>
687 template<typename _Alloc>
688 void
689 vector<bool, _Alloc>::
690 _M_reallocate(size_type __n)
691 {
692 _Bit_type* __q = this->_M_allocate(__n);
693 this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
694 iterator(__q, 0));
695 this->_M_deallocate();
696 this->_M_impl._M_start = iterator(__q, 0);
697 this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
698 }
699
700 template<typename _Alloc>
701 void
702 vector<bool, _Alloc>::
703 _M_fill_insert(iterator __position, size_type __n, bool __x)
704 {
705 if (__n == 0)
706 return;
707 if (capacity() - size() >= __n)
708 {
709 std::copy_backward(__position, end(),
710 this->_M_impl._M_finish + difference_type(__n));
711 std::fill(__position, __position + difference_type(__n), __x);
712 this->_M_impl._M_finish += difference_type(__n);
713 }
714 else
715 {
716 const size_type __len =
717 _M_check_len(__n, "vector<bool>::_M_fill_insert");
718 _Bit_type * __q = this->_M_allocate(__len);
719 iterator __i = _M_copy_aligned(begin(), __position,
720 iterator(__q, 0));
721 std::fill(__i, __i + difference_type(__n), __x);
722 this->_M_impl._M_finish = std::copy(__position, end(),
723 __i + difference_type(__n));
724 this->_M_deallocate();
725 this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
726 this->_M_impl._M_start = iterator(__q, 0);
727 }
728 }
729
730 template<typename _Alloc>
731 template<typename _ForwardIterator>
732 void
733 vector<bool, _Alloc>::
734 _M_insert_range(iterator __position, _ForwardIterator __first,
735 _ForwardIterator __last, std::forward_iterator_tag)
736 {
737 if (__first != __last)
738 {
739 size_type __n = std::distance(__first, __last);
740 if (capacity() - size() >= __n)
741 {
742 std::copy_backward(__position, end(),
743 this->_M_impl._M_finish
744 + difference_type(__n));
745 std::copy(__first, __last, __position);
746 this->_M_impl._M_finish += difference_type(__n);
747 }
748 else
749 {
750 const size_type __len =
751 _M_check_len(__n, "vector<bool>::_M_insert_range");
752 _Bit_type * __q = this->_M_allocate(__len);
753 iterator __i = _M_copy_aligned(begin(), __position,
754 iterator(__q, 0));
755 __i = std::copy(__first, __last, __i);
756 this->_M_impl._M_finish = std::copy(__position, end(), __i);
757 this->_M_deallocate();
758 this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
759 this->_M_impl._M_start = iterator(__q, 0);
760 }
761 }
762 }
763
764 template<typename _Alloc>
765 void
766 vector<bool, _Alloc>::
767 _M_insert_aux(iterator __position, bool __x)
768 {
769 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
770 {
771 std::copy_backward(__position, this->_M_impl._M_finish,
772 this->_M_impl._M_finish + 1);
773 *__position = __x;
774 ++this->_M_impl._M_finish;
775 }
776 else
777 {
778 const size_type __len =
779 _M_check_len(size_type(1), "vector<bool>::_M_insert_aux");
780 _Bit_type * __q = this->_M_allocate(__len);
781 iterator __i = _M_copy_aligned(begin(), __position,
782 iterator(__q, 0));
783 *__i++ = __x;
784 this->_M_impl._M_finish = std::copy(__position, end(), __i);
785 this->_M_deallocate();
786 this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
787 this->_M_impl._M_start = iterator(__q, 0);
788 }
789 }
790
791 #if __cplusplus >= 201103L
792 template<typename _Alloc>
793 bool
794 vector<bool, _Alloc>::
795 _M_shrink_to_fit()
796 {
797 if (capacity() - size() < int(_S_word_bit))
798 return false;
799 __try
800 {
801 _M_reallocate(size());
802 return true;
803 }
804 __catch(...)
805 { return false; }
806 }
807 #endif
808
809 _GLIBCXX_END_NAMESPACE_CONTAINER
810 } // namespace std
811
812 #if __cplusplus >= 201103L
813
814 namespace std _GLIBCXX_VISIBILITY(default)
815 {
816 _GLIBCXX_BEGIN_NAMESPACE_VERSION
817
818 template<typename _Alloc>
819 size_t
820 hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>::
821 operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const noexcept
822 {
823 size_t __hash = 0;
824 using _GLIBCXX_STD_C::_S_word_bit;
825 using _GLIBCXX_STD_C::_Bit_type;
826
827 const size_t __words = __b.size() / _S_word_bit;
828 if (__words)
829 {
830 const size_t __clength = __words * sizeof(_Bit_type);
831 __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength);
832 }
833
834 const size_t __extrabits = __b.size() % _S_word_bit;
835 if (__extrabits)
836 {
837 _Bit_type __hiword = *__b._M_impl._M_finish._M_p;
838 __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits);
839
840 const size_t __clength
841 = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__;
842 if (__words)
843 __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash);
844 else
845 __hash = std::_Hash_impl::hash(&__hiword, __clength);
846 }
847
848 return __hash;
849 }
850
851 _GLIBCXX_END_NAMESPACE_VERSION
852 } // namespace std
853
854 #endif // C++11
855
856 #endif /* _VECTOR_TCC */