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