1// Vector implementation (out of line) -*- C++ -*- 
2 
3// Copyright (C) 2001-2019 Free Software Foundation, Inc. 
4// 
5// This file is part of the GNU ISO C++ Library. This library is free 
6// software; you can redistribute it and/or modify it under the 
7// terms of the GNU General Public License as published by the 
8// Free Software Foundation; either version 3, or (at your option) 
9// any later version. 
10 
11// This library is distributed in the hope that it will be useful, 
12// but WITHOUT ANY WARRANTY; without even the implied warranty of 
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
14// GNU General Public License for more details. 
15 
16// Under Section 7 of GPL version 3, you are granted additional 
17// permissions described in the GCC Runtime Library Exception, version 
18// 3.1, as published by the Free Software Foundation. 
19 
20// You should have received a copy of the GNU General Public License and 
21// a copy of the GCC Runtime Library Exception along with this program; 
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 
23// <http://www.gnu.org/licenses/>. 
24 
25/* 
26 * 
27 * Copyright (c) 1994 
28 * Hewlett-Packard Company 
29 * 
30 * Permission to use, copy, modify, distribute and sell this software 
31 * and its documentation for any purpose is hereby granted without fee, 
32 * provided that the above copyright notice appear in all copies and 
33 * that both that copyright notice and this permission notice appear 
34 * in supporting documentation. Hewlett-Packard Company makes no 
35 * representations about the suitability of this software for any 
36 * purpose. It is provided "as is" without express or implied warranty. 
37 * 
38 * 
39 * Copyright (c) 1996 
40 * Silicon Graphics Computer Systems, Inc. 
41 * 
42 * Permission to use, copy, modify, distribute and sell this software 
43 * and its documentation for any purpose is hereby granted without fee, 
44 * provided that the above copyright notice appear in all copies and 
45 * that both that copyright notice and this permission notice appear 
46 * in supporting documentation. Silicon Graphics makes no 
47 * representations about the suitability of this software for any 
48 * purpose. It is provided "as is" without express or implied warranty. 
49 */ 
50 
51/** @file bits/vector.tcc 
52 * This is an internal header file, included by other library headers. 
53 * Do not attempt to use it directly. @headername{vector} 
54 */ 
55 
56#ifndef _VECTOR_TCC 
57#define _VECTOR_TCC 1 
58 
59namespace std _GLIBCXX_VISIBILITY(default) 
60{ 
61_GLIBCXX_BEGIN_NAMESPACE_VERSION 
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; 
75#if __cplusplus >= 201103L 
76 if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) 
77 { 
78 __tmp = this->_M_allocate(__n); 
79 _S_relocate(this->_M_impl._M_start, this->_M_impl._M_finish, 
80 __tmp, _M_get_Tp_allocator()); 
81 } 
82 else 
83#endif 
84 { 
85 __tmp = _M_allocate_and_copy(__n, 
86 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), 
87 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); 
88 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
89 _M_get_Tp_allocator()); 
90 } 
91 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
92 _M_deallocate(this->_M_impl._M_start, 
93 this->_M_impl._M_end_of_storage 
94 - this->_M_impl._M_start); 
95 this->_M_impl._M_start = __tmp; 
96 this->_M_impl._M_finish = __tmp + __old_size; 
97 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 
98 } 
99 } 
100 
101#if __cplusplus >= 201103L 
102 template<typename _Tp, typename _Alloc> 
103 template<typename... _Args> 
104#if __cplusplus > 201402L 
105 typename vector<_Tp, _Alloc>::reference 
106#else 
107 void 
108#endif 
109 vector<_Tp, _Alloc>:: 
110 emplace_back(_Args&&... __args) 
111 { 
112 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 
113 { 
114 _GLIBCXX_ASAN_ANNOTATE_GROW(1); 
115 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 
116 std::forward<_Args>(__args)...); 
117 ++this->_M_impl._M_finish; 
118 _GLIBCXX_ASAN_ANNOTATE_GREW(1); 
119 } 
120 else 
121 _M_realloc_insert(end(), std::forward<_Args>(__args)...); 
122#if __cplusplus > 201402L 
123 return back(); 
124#endif 
125 } 
126#endif 
127 
128 template<typename _Tp, typename _Alloc> 
129 typename vector<_Tp, _Alloc>::iterator 
130 vector<_Tp, _Alloc>:: 
131#if __cplusplus >= 201103L 
132 insert(const_iterator __position, const value_type& __x) 
133#else 
134 insert(iterator __position, const value_type& __x) 
135#endif 
136 { 
137 const size_type __n = __position - begin(); 
138 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 
139 if (__position == end()) 
140 { 
141 _GLIBCXX_ASAN_ANNOTATE_GROW(1); 
142 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 
143 __x); 
144 ++this->_M_impl._M_finish; 
145 _GLIBCXX_ASAN_ANNOTATE_GREW(1); 
146 } 
147 else 
148 { 
149#if __cplusplus >= 201103L 
150 const auto __pos = begin() + (__position - cbegin()); 
151 // __x could be an existing element of this vector, so make a 
152 // copy of it before _M_insert_aux moves elements around. 
153 _Temporary_value __x_copy(this, __x); 
154 _M_insert_aux(__pos, std::move(__x_copy._M_val())); 
155#else 
156 _M_insert_aux(__position, __x); 
157#endif 
158 } 
159 else 
160#if __cplusplus >= 201103L 
161 _M_realloc_insert(begin() + (__position - cbegin()), __x); 
162#else 
163 _M_realloc_insert(__position, __x); 
164#endif 
165 
166 return iterator(this->_M_impl._M_start + __n); 
167 } 
168 
169 template<typename _Tp, typename _Alloc> 
170 typename vector<_Tp, _Alloc>::iterator 
171 vector<_Tp, _Alloc>:: 
172 _M_erase(iterator __position) 
173 { 
174 if (__position + 1 != end()) 
175 _GLIBCXX_MOVE3(__position + 1, end(), __position); 
176 --this->_M_impl._M_finish; 
177 _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); 
178 _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); 
179 return __position; 
180 } 
181 
182 template<typename _Tp, typename _Alloc> 
183 typename vector<_Tp, _Alloc>::iterator 
184 vector<_Tp, _Alloc>:: 
185 _M_erase(iterator __first, iterator __last) 
186 { 
187 if (__first != __last) 
188 { 
189 if (__last != end()) 
190 _GLIBCXX_MOVE3(__last, end(), __first); 
191 _M_erase_at_end(__first.base() + (end() - __last)); 
192 } 
193 return __first; 
194 } 
195 
196 template<typename _Tp, typename _Alloc> 
197 vector<_Tp, _Alloc>& 
198 vector<_Tp, _Alloc>:: 
199 operator=(const vector<_Tp, _Alloc>& __x) 
200 { 
201 if (&__x != this) 
202 { 
203 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
204#if __cplusplus >= 201103L 
205 if (_Alloc_traits::_S_propagate_on_copy_assign()) 
206 { 
207 if (!_Alloc_traits::_S_always_equal() 
208 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator()) 
209 { 
210 // replacement allocator cannot free existing storage 
211 this->clear(); 
212 _M_deallocate(this->_M_impl._M_start, 
213 this->_M_impl._M_end_of_storage 
214 - this->_M_impl._M_start); 
215 this->_M_impl._M_start = nullptr; 
216 this->_M_impl._M_finish = nullptr; 
217 this->_M_impl._M_end_of_storage = nullptr; 
218 } 
219 std::__alloc_on_copy(_M_get_Tp_allocator(), 
220 __x._M_get_Tp_allocator()); 
221 } 
222#endif 
223 const size_type __xlen = __x.size(); 
224 if (__xlen > capacity()) 
225 { 
226 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), 
227 __x.end()); 
228 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
229 _M_get_Tp_allocator()); 
230 _M_deallocate(this->_M_impl._M_start, 
231 this->_M_impl._M_end_of_storage 
232 - this->_M_impl._M_start); 
233 this->_M_impl._M_start = __tmp; 
234 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; 
235 } 
236 else if (size() >= __xlen) 
237 { 
238 std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), 
239 end(), _M_get_Tp_allocator()); 
240 } 
241 else 
242 { 
243 std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), 
244 this->_M_impl._M_start); 
245 std::__uninitialized_copy_a(__x._M_impl._M_start + size(), 
246 __x._M_impl._M_finish, 
247 this->_M_impl._M_finish, 
248 _M_get_Tp_allocator()); 
249 } 
250 this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; 
251 } 
252 return *this; 
253 } 
254 
255 template<typename _Tp, typename _Alloc> 
256 void 
257 vector<_Tp, _Alloc>:: 
258 _M_fill_assign(size_t __n, const value_type& __val) 
259 { 
260 if (__n > capacity()) 
261 { 
262 vector __tmp(__n, __val, _M_get_Tp_allocator()); 
263 __tmp._M_impl._M_swap_data(this->_M_impl); 
264 } 
265 else if (__n > size()) 
266 { 
267 std::fill(begin(), end(), __val); 
268 const size_type __add = __n - size(); 
269 _GLIBCXX_ASAN_ANNOTATE_GROW(__add); 
270 this->_M_impl._M_finish = 
271 std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 
272 __add, __val, _M_get_Tp_allocator()); 
273 _GLIBCXX_ASAN_ANNOTATE_GREW(__add); 
274 } 
275 else 
276 _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); 
277 } 
278 
279 template<typename _Tp, typename _Alloc> 
280 template<typename _InputIterator> 
281 void 
282 vector<_Tp, _Alloc>:: 
283 _M_assign_aux(_InputIterator __first, _InputIterator __last, 
284 std::input_iterator_tag) 
285 { 
286 pointer __cur(this->_M_impl._M_start); 
287 for (; __first != __last && __cur != this->_M_impl._M_finish; 
288 ++__cur, (void)++__first) 
289 *__cur = *__first; 
290 if (__first == __last) 
291 _M_erase_at_end(__cur); 
292 else 
293 _M_range_insert(end(), __first, __last, 
294 std::__iterator_category(__first)); 
295 } 
296 
297 template<typename _Tp, typename _Alloc> 
298 template<typename _ForwardIterator> 
299 void 
300 vector<_Tp, _Alloc>:: 
301 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 
302 std::forward_iterator_tag) 
303 { 
304 const size_type __len = std::distance(__first, __last); 
305 
306 if (__len > capacity()) 
307 { 
308 _S_check_init_len(__len, _M_get_Tp_allocator()); 
309 pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); 
310 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
311 _M_get_Tp_allocator()); 
312 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
313 _M_deallocate(this->_M_impl._M_start, 
314 this->_M_impl._M_end_of_storage 
315 - this->_M_impl._M_start); 
316 this->_M_impl._M_start = __tmp; 
317 this->_M_impl._M_finish = this->_M_impl._M_start + __len; 
318 this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; 
319 } 
320 else if (size() >= __len) 
321 _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); 
322 else 
323 { 
324 _ForwardIterator __mid = __first; 
325 std::advance(__mid, size()); 
326 std::copy(__first, __mid, this->_M_impl._M_start); 
327 const size_type __attribute__((__unused__)) __n = __len - size(); 
328 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
329 this->_M_impl._M_finish = 
330 std::__uninitialized_copy_a(__mid, __last, 
331 this->_M_impl._M_finish, 
332 _M_get_Tp_allocator()); 
333 _GLIBCXX_ASAN_ANNOTATE_GREW(__n); 
334 } 
335 } 
336 
337#if __cplusplus >= 201103L 
338 template<typename _Tp, typename _Alloc> 
339 auto 
340 vector<_Tp, _Alloc>:: 
341 _M_insert_rval(const_iterator __position, value_type&& __v) -> iterator 
342 { 
343 const auto __n = __position - cbegin(); 
344 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 
345 if (__position == cend()) 
346 { 
347 _GLIBCXX_ASAN_ANNOTATE_GROW(1); 
348 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 
349 std::move(__v)); 
350 ++this->_M_impl._M_finish; 
351 _GLIBCXX_ASAN_ANNOTATE_GREW(1); 
352 } 
353 else 
354 _M_insert_aux(begin() + __n, std::move(__v)); 
355 else 
356 _M_realloc_insert(begin() + __n, std::move(__v)); 
357 
358 return iterator(this->_M_impl._M_start + __n); 
359 } 
360 
361 template<typename _Tp, typename _Alloc> 
362 template<typename... _Args> 
363 auto 
364 vector<_Tp, _Alloc>:: 
365 _M_emplace_aux(const_iterator __position, _Args&&... __args) 
366 -> iterator 
367 { 
368 const auto __n = __position - cbegin(); 
369 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 
370 if (__position == cend()) 
371 { 
372 _GLIBCXX_ASAN_ANNOTATE_GROW(1); 
373 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 
374 std::forward<_Args>(__args)...); 
375 ++this->_M_impl._M_finish; 
376 _GLIBCXX_ASAN_ANNOTATE_GREW(1); 
377 } 
378 else 
379 { 
380 // We need to construct a temporary because something in __args... 
381 // could alias one of the elements of the container and so we 
382 // need to use it before _M_insert_aux moves elements around. 
383 _Temporary_value __tmp(this, std::forward<_Args>(__args)...); 
384 _M_insert_aux(begin() + __n, std::move(__tmp._M_val())); 
385 } 
386 else 
387 _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...); 
388 
389 return iterator(this->_M_impl._M_start + __n); 
390 } 
391 
392 template<typename _Tp, typename _Alloc> 
393 template<typename _Arg> 
394 void 
395 vector<_Tp, _Alloc>:: 
396 _M_insert_aux(iterator __position, _Arg&& __arg) 
397#else 
398 template<typename _Tp, typename _Alloc> 
399 void 
400 vector<_Tp, _Alloc>:: 
401 _M_insert_aux(iterator __position, const _Tp& __x) 
402#endif 
403 { 
404 _GLIBCXX_ASAN_ANNOTATE_GROW(1); 
405 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 
406 _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1))); 
407 ++this->_M_impl._M_finish; 
408 _GLIBCXX_ASAN_ANNOTATE_GREW(1); 
409#if __cplusplus < 201103L 
410 _Tp __x_copy = __x; 
411#endif 
412 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 
413 this->_M_impl._M_finish - 2, 
414 this->_M_impl._M_finish - 1); 
415#if __cplusplus < 201103L 
416 *__position = __x_copy; 
417#else 
418 *__position = std::forward<_Arg>(__arg); 
419#endif 
420 } 
421 
422#if __cplusplus >= 201103L 
423 template<typename _Tp, typename _Alloc> 
424 template<typename... _Args> 
425 void 
426 vector<_Tp, _Alloc>:: 
427 _M_realloc_insert(iterator __position, _Args&&... __args) 
428#else 
429 template<typename _Tp, typename _Alloc> 
430 void 
431 vector<_Tp, _Alloc>:: 
432 _M_realloc_insert(iterator __position, const _Tp& __x) 
433#endif 
434 { 
435 const size_type __len = 
436 _M_check_len(size_type(1), "vector::_M_realloc_insert"); 
437 pointer __old_start = this->_M_impl._M_start; 
438 pointer __old_finish = this->_M_impl._M_finish; 
439 const size_type __elems_before = __position - begin(); 
440 pointer __new_start(this->_M_allocate(__len)); 
441 pointer __new_finish(__new_start); 
442 __try 
443 { 
444 // The order of the three operations is dictated by the C++11 
445 // case, where the moves could alter a new element belonging 
446 // to the existing vector. This is an issue only for callers 
447 // taking the element by lvalue ref (see last bullet of C++11 
448 // [res.on.arguments]). 
449 _Alloc_traits::construct(this->_M_impl, 
450 __new_start + __elems_before, 
451#if __cplusplus >= 201103L 
452 std::forward<_Args>(__args)...); 
453#else 
454 __x); 
455#endif 
456 __new_finish = pointer(); 
457 
458#if __cplusplus >= 201103L 
459 if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) 
460 { 
461 __new_finish = _S_relocate(__old_start, __position.base(), 
462 __new_start, _M_get_Tp_allocator()); 
463 
464 ++__new_finish; 
465 
466 __new_finish = _S_relocate(__position.base(), __old_finish, 
467 __new_finish, _M_get_Tp_allocator()); 
468 } 
469 else 
470#endif 
471 { 
472 __new_finish 
473 = std::__uninitialized_move_if_noexcept_a 
474 (__old_start, __position.base(), 
475 __new_start, _M_get_Tp_allocator()); 
476 
477 ++__new_finish; 
478 
479 __new_finish 
480 = std::__uninitialized_move_if_noexcept_a 
481 (__position.base(), __old_finish, 
482 __new_finish, _M_get_Tp_allocator()); 
483 } 
484 } 
485 __catch(...) 
486 { 
487 if (!__new_finish) 
488 _Alloc_traits::destroy(this->_M_impl, 
489 __new_start + __elems_before); 
490 else 
491 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); 
492 _M_deallocate(__new_start, __len); 
493 __throw_exception_again; 
494 } 
495#if __cplusplus >= 201103L 
496 if _GLIBCXX17_CONSTEXPR (!_S_use_relocate()) 
497#endif 
498 std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator()); 
499 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
500 _M_deallocate(__old_start, 
501 this->_M_impl._M_end_of_storage - __old_start); 
502 this->_M_impl._M_start = __new_start; 
503 this->_M_impl._M_finish = __new_finish; 
504 this->_M_impl._M_end_of_storage = __new_start + __len; 
505 } 
506 
507 template<typename _Tp, typename _Alloc> 
508 void 
509 vector<_Tp, _Alloc>:: 
510 _M_fill_insert(iterator __position, size_type __n, const value_type& __x) 
511 { 
512 if (__n != 0) 
513 { 
514 if (size_type(this->_M_impl._M_end_of_storage 
515 - this->_M_impl._M_finish) >= __n) 
516 { 
517#if __cplusplus < 201103L 
518 value_type __x_copy = __x; 
519#else 
520 _Temporary_value __tmp(this, __x); 
521 value_type& __x_copy = __tmp._M_val(); 
522#endif 
523 const size_type __elems_after = end() - __position; 
524 pointer __old_finish(this->_M_impl._M_finish); 
525 if (__elems_after > __n) 
526 { 
527 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
528 std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 
529 this->_M_impl._M_finish, 
530 this->_M_impl._M_finish, 
531 _M_get_Tp_allocator()); 
532 this->_M_impl._M_finish += __n; 
533 _GLIBCXX_ASAN_ANNOTATE_GREW(__n); 
534 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 
535 __old_finish - __n, __old_finish); 
536 std::fill(__position.base(), __position.base() + __n, 
537 __x_copy); 
538 } 
539 else 
540 { 
541 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
542 this->_M_impl._M_finish = 
543 std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 
544 __n - __elems_after, 
545 __x_copy, 
546 _M_get_Tp_allocator()); 
547 _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); 
548 std::__uninitialized_move_a(__position.base(), __old_finish, 
549 this->_M_impl._M_finish, 
550 _M_get_Tp_allocator()); 
551 this->_M_impl._M_finish += __elems_after; 
552 _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); 
553 std::fill(__position.base(), __old_finish, __x_copy); 
554 } 
555 } 
556 else 
557 { 
558 const size_type __len = 
559 _M_check_len(__n, "vector::_M_fill_insert"); 
560 const size_type __elems_before = __position - begin(); 
561 pointer __new_start(this->_M_allocate(__len)); 
562 pointer __new_finish(__new_start); 
563 __try 
564 { 
565 // See _M_realloc_insert above. 
566 std::__uninitialized_fill_n_a(__new_start + __elems_before, 
567 __n, __x, 
568 _M_get_Tp_allocator()); 
569 __new_finish = pointer(); 
570 
571 __new_finish 
572 = std::__uninitialized_move_if_noexcept_a 
573 (this->_M_impl._M_start, __position.base(), 
574 __new_start, _M_get_Tp_allocator()); 
575 
576 __new_finish += __n; 
577 
578 __new_finish 
579 = std::__uninitialized_move_if_noexcept_a 
580 (__position.base(), this->_M_impl._M_finish, 
581 __new_finish, _M_get_Tp_allocator()); 
582 } 
583 __catch(...) 
584 { 
585 if (!__new_finish) 
586 std::_Destroy(__new_start + __elems_before, 
587 __new_start + __elems_before + __n, 
588 _M_get_Tp_allocator()); 
589 else 
590 std::_Destroy(__new_start, __new_finish, 
591 _M_get_Tp_allocator()); 
592 _M_deallocate(__new_start, __len); 
593 __throw_exception_again; 
594 } 
595 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
596 _M_get_Tp_allocator()); 
597 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
598 _M_deallocate(this->_M_impl._M_start, 
599 this->_M_impl._M_end_of_storage 
600 - this->_M_impl._M_start); 
601 this->_M_impl._M_start = __new_start; 
602 this->_M_impl._M_finish = __new_finish; 
603 this->_M_impl._M_end_of_storage = __new_start + __len; 
604 } 
605 } 
606 } 
607 
608#if __cplusplus >= 201103L 
609 template<typename _Tp, typename _Alloc> 
610 void 
611 vector<_Tp, _Alloc>:: 
612 _M_default_append(size_type __n) 
613 { 
614 if (__n != 0) 
615 { 
616 const size_type __size = size(); 
617 size_type __navail = size_type(this->_M_impl._M_end_of_storage 
618 - this->_M_impl._M_finish); 
619 
620 if (__size > max_size() || __navail > max_size() - __size) 
621 __builtin_unreachable(); 
622 
623 if (__navail >= __n) 
624 { 
625 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
626 this->_M_impl._M_finish = 
627 std::__uninitialized_default_n_a(this->_M_impl._M_finish, 
628 __n, _M_get_Tp_allocator()); 
629 _GLIBCXX_ASAN_ANNOTATE_GREW(__n); 
630 } 
631 else 
632 { 
633 const size_type __len = 
634 _M_check_len(__n, "vector::_M_default_append"); 
635 pointer __new_start(this->_M_allocate(__len)); 
636 if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) 
637 { 
638 __try 
639 { 
640 std::__uninitialized_default_n_a(__new_start + __size, 
641 __n, _M_get_Tp_allocator()); 
642 } 
643 __catch(...) 
644 { 
645 _M_deallocate(__new_start, __len); 
646 __throw_exception_again; 
647 } 
648 _S_relocate(this->_M_impl._M_start, this->_M_impl._M_finish, 
649 __new_start, _M_get_Tp_allocator()); 
650 } 
651 else 
652 { 
653 pointer __destroy_from = pointer(); 
654 __try 
655 { 
656 std::__uninitialized_default_n_a(__new_start + __size, 
657 __n, _M_get_Tp_allocator()); 
658 __destroy_from = __new_start + __size; 
659 std::__uninitialized_move_if_noexcept_a( 
660 this->_M_impl._M_start, this->_M_impl._M_finish, 
661 __new_start, _M_get_Tp_allocator()); 
662 } 
663 __catch(...) 
664 { 
665 if (__destroy_from) 
666 std::_Destroy(__destroy_from, __destroy_from + __n, 
667 _M_get_Tp_allocator()); 
668 _M_deallocate(__new_start, __len); 
669 __throw_exception_again; 
670 } 
671 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
672 _M_get_Tp_allocator()); 
673 } 
674 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
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_start + __size + __n; 
680 this->_M_impl._M_end_of_storage = __new_start + __len; 
681 } 
682 } 
683 } 
684 
685 template<typename _Tp, typename _Alloc> 
686 bool 
687 vector<_Tp, _Alloc>:: 
688 _M_shrink_to_fit() 
689 { 
690 if (capacity() == size()) 
691 return false; 
692 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
693 return std::__shrink_to_fit_aux<vector>::_S_do_it(*this); 
694 } 
695#endif 
696 
697 template<typename _Tp, typename _Alloc> 
698 template<typename _InputIterator> 
699 void 
700 vector<_Tp, _Alloc>:: 
701 _M_range_insert(iterator __pos, _InputIterator __first, 
702 _InputIterator __last, std::input_iterator_tag) 
703 { 
704 if (__pos == end()) 
705 { 
706 for (; __first != __last; ++__first) 
707 insert(end(), *__first); 
708 } 
709 else if (__first != __last) 
710 { 
711 vector __tmp(__first, __last, _M_get_Tp_allocator()); 
712 insert(__pos, 
713 _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.begin()), 
714 _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.end())); 
715 } 
716 } 
717 
718 template<typename _Tp, typename _Alloc> 
719 template<typename _ForwardIterator> 
720 void 
721 vector<_Tp, _Alloc>:: 
722 _M_range_insert(iterator __position, _ForwardIterator __first, 
723 _ForwardIterator __last, std::forward_iterator_tag) 
724 { 
725 if (__first != __last) 
726 { 
727 const size_type __n = std::distance(__first, __last); 
728 if (size_type(this->_M_impl._M_end_of_storage 
729 - this->_M_impl._M_finish) >= __n) 
730 { 
731 const size_type __elems_after = end() - __position; 
732 pointer __old_finish(this->_M_impl._M_finish); 
733 if (__elems_after > __n) 
734 { 
735 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
736 std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 
737 this->_M_impl._M_finish, 
738 this->_M_impl._M_finish, 
739 _M_get_Tp_allocator()); 
740 this->_M_impl._M_finish += __n; 
741 _GLIBCXX_ASAN_ANNOTATE_GREW(__n); 
742 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 
743 __old_finish - __n, __old_finish); 
744 std::copy(__first, __last, __position); 
745 } 
746 else 
747 { 
748 _ForwardIterator __mid = __first; 
749 std::advance(__mid, __elems_after); 
750 _GLIBCXX_ASAN_ANNOTATE_GROW(__n); 
751 std::__uninitialized_copy_a(__mid, __last, 
752 this->_M_impl._M_finish, 
753 _M_get_Tp_allocator()); 
754 this->_M_impl._M_finish += __n - __elems_after; 
755 _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); 
756 std::__uninitialized_move_a(__position.base(), 
757 __old_finish, 
758 this->_M_impl._M_finish, 
759 _M_get_Tp_allocator()); 
760 this->_M_impl._M_finish += __elems_after; 
761 _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); 
762 std::copy(__first, __mid, __position); 
763 } 
764 } 
765 else 
766 { 
767 const size_type __len = 
768 _M_check_len(__n, "vector::_M_range_insert"); 
769 pointer __new_start(this->_M_allocate(__len)); 
770 pointer __new_finish(__new_start); 
771 __try 
772 { 
773 __new_finish 
774 = std::__uninitialized_move_if_noexcept_a 
775 (this->_M_impl._M_start, __position.base(), 
776 __new_start, _M_get_Tp_allocator()); 
777 __new_finish 
778 = std::__uninitialized_copy_a(__first, __last, 
779 __new_finish, 
780 _M_get_Tp_allocator()); 
781 __new_finish 
782 = std::__uninitialized_move_if_noexcept_a 
783 (__position.base(), this->_M_impl._M_finish, 
784 __new_finish, _M_get_Tp_allocator()); 
785 } 
786 __catch(...) 
787 { 
788 std::_Destroy(__new_start, __new_finish, 
789 _M_get_Tp_allocator()); 
790 _M_deallocate(__new_start, __len); 
791 __throw_exception_again; 
792 } 
793 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
794 _M_get_Tp_allocator()); 
795 _GLIBCXX_ASAN_ANNOTATE_REINIT; 
796 _M_deallocate(this->_M_impl._M_start, 
797 this->_M_impl._M_end_of_storage 
798 - this->_M_impl._M_start); 
799 this->_M_impl._M_start = __new_start; 
800 this->_M_impl._M_finish = __new_finish; 
801 this->_M_impl._M_end_of_storage = __new_start + __len; 
802 } 
803 } 
804 } 
805 
806 
807 // vector<bool> 
808 template<typename _Alloc> 
809 void 
810 vector<bool, _Alloc>:: 
811 _M_reallocate(size_type __n) 
812 { 
813 _Bit_pointer __q = this->_M_allocate(__n); 
814 iterator __start(std::__addressof(*__q), 0); 
815 iterator __finish(_M_copy_aligned(begin(), end(), __start)); 
816 this->_M_deallocate(); 
817 this->_M_impl._M_start = __start; 
818 this->_M_impl._M_finish = __finish; 
819 this->_M_impl._M_end_of_storage = __q + _S_nword(__n); 
820 } 
821 
822 template<typename _Alloc> 
823 void 
824 vector<bool, _Alloc>:: 
825 _M_fill_insert(iterator __position, size_type __n, bool __x) 
826 { 
827 if (__n == 0) 
828 return; 
829 if (capacity() - size() >= __n) 
830 { 
831 std::copy_backward(__position, end(), 
832 this->_M_impl._M_finish + difference_type(__n)); 
833 std::fill(__position, __position + difference_type(__n), __x); 
834 this->_M_impl._M_finish += difference_type(__n); 
835 } 
836 else 
837 { 
838 const size_type __len =  
839 _M_check_len(__n, "vector<bool>::_M_fill_insert"); 
840 _Bit_pointer __q = this->_M_allocate(__len); 
841 iterator __start(std::__addressof(*__q), 0); 
842 iterator __i = _M_copy_aligned(begin(), __position, __start); 
843 std::fill(__i, __i + difference_type(__n), __x); 
844 iterator __finish = std::copy(__position, end(), 
845 __i + difference_type(__n)); 
846 this->_M_deallocate(); 
847 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 
848 this->_M_impl._M_start = __start; 
849 this->_M_impl._M_finish = __finish; 
850 } 
851 } 
852 
853 template<typename _Alloc> 
854 template<typename _ForwardIterator> 
855 void 
856 vector<bool, _Alloc>:: 
857 _M_insert_range(iterator __position, _ForwardIterator __first,  
858 _ForwardIterator __last, std::forward_iterator_tag) 
859 { 
860 if (__first != __last) 
861 { 
862 size_type __n = std::distance(__first, __last); 
863 if (capacity() - size() >= __n) 
864 { 
865 std::copy_backward(__position, end(), 
866 this->_M_impl._M_finish 
867 + difference_type(__n)); 
868 std::copy(__first, __last, __position); 
869 this->_M_impl._M_finish += difference_type(__n); 
870 } 
871 else 
872 { 
873 const size_type __len = 
874 _M_check_len(__n, "vector<bool>::_M_insert_range"); 
875 _Bit_pointer __q = this->_M_allocate(__len); 
876 iterator __start(std::__addressof(*__q), 0); 
877 iterator __i = _M_copy_aligned(begin(), __position, __start); 
878 __i = std::copy(__first, __last, __i); 
879 iterator __finish = std::copy(__position, end(), __i); 
880 this->_M_deallocate(); 
881 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 
882 this->_M_impl._M_start = __start; 
883 this->_M_impl._M_finish = __finish; 
884 } 
885 } 
886 } 
887 
888 template<typename _Alloc> 
889 void 
890 vector<bool, _Alloc>:: 
891 _M_insert_aux(iterator __position, bool __x) 
892 { 
893 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()) 
894 { 
895 std::copy_backward(__position, this->_M_impl._M_finish,  
896 this->_M_impl._M_finish + 1); 
897 *__position = __x; 
898 ++this->_M_impl._M_finish; 
899 } 
900 else 
901 { 
902 const size_type __len = 
903 _M_check_len(size_type(1), "vector<bool>::_M_insert_aux"); 
904 _Bit_pointer __q = this->_M_allocate(__len); 
905 iterator __start(std::__addressof(*__q), 0); 
906 iterator __i = _M_copy_aligned(begin(), __position, __start); 
907 *__i++ = __x; 
908 iterator __finish = std::copy(__position, end(), __i); 
909 this->_M_deallocate(); 
910 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 
911 this->_M_impl._M_start = __start; 
912 this->_M_impl._M_finish = __finish; 
913 } 
914 } 
915 
916 template<typename _Alloc> 
917 typename vector<bool, _Alloc>::iterator 
918 vector<bool, _Alloc>:: 
919 _M_erase(iterator __position) 
920 { 
921 if (__position + 1 != end()) 
922 std::copy(__position + 1, end(), __position); 
923 --this->_M_impl._M_finish; 
924 return __position; 
925 } 
926 
927 template<typename _Alloc> 
928 typename vector<bool, _Alloc>::iterator 
929 vector<bool, _Alloc>:: 
930 _M_erase(iterator __first, iterator __last) 
931 { 
932 if (__first != __last) 
933 _M_erase_at_end(std::copy(__last, end(), __first)); 
934 return __first; 
935 } 
936 
937#if __cplusplus >= 201103L 
938 template<typename _Alloc> 
939 bool 
940 vector<bool, _Alloc>:: 
941 _M_shrink_to_fit() 
942 { 
943 if (capacity() - size() < int(_S_word_bit)) 
944 return false; 
945 __try 
946 { 
947 _M_reallocate(size()); 
948 return true; 
949 } 
950 __catch(...) 
951 { return false; } 
952 } 
953#endif 
954 
955_GLIBCXX_END_NAMESPACE_CONTAINER 
956_GLIBCXX_END_NAMESPACE_VERSION 
957} // namespace std 
958 
959#if __cplusplus >= 201103L 
960 
961namespace std _GLIBCXX_VISIBILITY(default) 
962{ 
963_GLIBCXX_BEGIN_NAMESPACE_VERSION 
964 
965 template<typename _Alloc> 
966 size_t 
967 hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>:: 
968 operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const noexcept 
969 { 
970 size_t __hash = 0; 
971 using _GLIBCXX_STD_C::_S_word_bit; 
972 using _GLIBCXX_STD_C::_Bit_type; 
973 
974 const size_t __words = __b.size() / _S_word_bit; 
975 if (__words) 
976 { 
977 const size_t __clength = __words * sizeof(_Bit_type); 
978 __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength); 
979 } 
980 
981 const size_t __extrabits = __b.size() % _S_word_bit; 
982 if (__extrabits) 
983 { 
984 _Bit_type __hiword = *__b._M_impl._M_finish._M_p; 
985 __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits); 
986 
987 const size_t __clength 
988 = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__; 
989 if (__words) 
990 __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash); 
991 else 
992 __hash = std::_Hash_impl::hash(&__hiword, __clength); 
993 } 
994 
995 return __hash; 
996 } 
997 
998_GLIBCXX_END_NAMESPACE_VERSION 
999} // namespace std 
1000 
1001#endif // C++11 
1002 
1003#undef _GLIBCXX_ASAN_ANNOTATE_REINIT 
1004#undef _GLIBCXX_ASAN_ANNOTATE_GROW 
1005#undef _GLIBCXX_ASAN_ANNOTATE_GREW 
1006#undef _GLIBCXX_ASAN_ANNOTATE_SHRINK 
1007 
1008#endif /* _VECTOR_TCC */ 
1009