1 // Vector implementation (out of line) -*- C++ -*-
2 
3 // Copyright (C) 2001-2020 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 
59 namespace 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>::
reserve(size_type __n)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>::
emplace_back(_Args &&...__args)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
insert(const_iterator __position,const value_type & __x)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>::
_M_erase(iterator __position)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>::
_M_erase(iterator __first,iterator __last)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>::
operator =(const vector<_Tp,_Alloc> & __x)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>::
_M_fill_assign(size_t __n,const value_type & __val)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>::
_M_assign_aux(_InputIterator __first,_InputIterator __last,std::input_iterator_tag)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>::
_M_assign_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)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>::
_M_insert_rval(const_iterator __position,value_type && __v)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>::
_M_emplace_aux(const_iterator __position,_Args &&...__args)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>::
_M_insert_aux(iterator __position,_Arg && __arg)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>::
_M_realloc_insert(iterator __position,_Args &&...__args)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>::
_M_fill_insert(iterator __position,size_type __n,const value_type & __x)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>::
_M_default_append(size_type __n)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>::
_M_shrink_to_fit()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>::
_M_range_insert(iterator __pos,_InputIterator __first,_InputIterator __last,std::input_iterator_tag)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>::
_M_range_insert(iterator __position,_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)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>::
_M_reallocate(size_type __n)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>::
_M_fill_insert(iterator __position,size_type __n,bool __x)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>::
_M_insert_range(iterator __position,_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)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>::
_M_insert_aux(iterator __position,bool __x)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>::
_M_erase(iterator __position)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>::
_M_erase(iterator __first,iterator __last)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>::
_M_shrink_to_fit()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 
961 namespace 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>>::
operator ()(const _GLIBCXX_STD_C::vector<bool,_Alloc> & __b) const968     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