Home | History | Annotate | Line # | Download | only in bits
      1 // Vector implementation (out of line) -*- C++ -*-
      2 
      3 // Copyright (C) 2001-2024 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>::
     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>::
    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_append(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
    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 	{
    143 	  __glibcxx_assert(__position != const_iterator());
    144 	  if (!(__position != const_iterator()))
    145 	    __builtin_unreachable(); // PR 106434
    146 
    147 	  if (__position == end())
    148 	    {
    149 	      _GLIBCXX_ASAN_ANNOTATE_GROW(1);
    150 	      _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    151 				       __x);
    152 	      ++this->_M_impl._M_finish;
    153 	      _GLIBCXX_ASAN_ANNOTATE_GREW(1);
    154 	    }
    155 	  else
    156 	    {
    157 #if __cplusplus >= 201103L
    158 	      const auto __pos = begin() + (__position - cbegin());
    159 	      // __x could be an existing element of this vector, so make a
    160 	      // copy of it before _M_insert_aux moves elements around.
    161 	      _Temporary_value __x_copy(this, __x);
    162 	      _M_insert_aux(__pos, std::move(__x_copy._M_val()));
    163 #else
    164 	      _M_insert_aux(__position, __x);
    165 #endif
    166 	    }
    167 	}
    168       else
    169 #if __cplusplus >= 201103L
    170 	_M_realloc_insert(begin() + (__position - cbegin()), __x);
    171 #else
    172 	_M_realloc_insert(__position, __x);
    173 #endif
    174 
    175       return iterator(this->_M_impl._M_start + __n);
    176     }
    177 
    178   template<typename _Tp, typename _Alloc>
    179     _GLIBCXX20_CONSTEXPR
    180     typename vector<_Tp, _Alloc>::iterator
    181     vector<_Tp, _Alloc>::
    182     _M_erase(iterator __position)
    183     {
    184       if (__position + 1 != end())
    185 	_GLIBCXX_MOVE3(__position + 1, end(), __position);
    186       --this->_M_impl._M_finish;
    187       _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
    188       _GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
    189       return __position;
    190     }
    191 
    192   template<typename _Tp, typename _Alloc>
    193     _GLIBCXX20_CONSTEXPR
    194     typename vector<_Tp, _Alloc>::iterator
    195     vector<_Tp, _Alloc>::
    196     _M_erase(iterator __first, iterator __last)
    197     {
    198       if (__first != __last)
    199 	{
    200 	  if (__last != end())
    201 	    _GLIBCXX_MOVE3(__last, end(), __first);
    202 	  _M_erase_at_end(__first.base() + (end() - __last));
    203 	}
    204       return __first;
    205     }
    206 
    207   template<typename _Tp, typename _Alloc>
    208     _GLIBCXX20_CONSTEXPR
    209     vector<_Tp, _Alloc>&
    210     vector<_Tp, _Alloc>::
    211     operator=(const vector<_Tp, _Alloc>& __x)
    212     {
    213       if (std::__addressof(__x) != this)
    214 	{
    215 	  _GLIBCXX_ASAN_ANNOTATE_REINIT;
    216 #if __cplusplus >= 201103L
    217 	  if (_Alloc_traits::_S_propagate_on_copy_assign())
    218 	    {
    219 	      if (!_Alloc_traits::_S_always_equal()
    220 	          && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
    221 	        {
    222 		  // replacement allocator cannot free existing storage
    223 		  this->clear();
    224 		  _M_deallocate(this->_M_impl._M_start,
    225 				this->_M_impl._M_end_of_storage
    226 				- this->_M_impl._M_start);
    227 		  this->_M_impl._M_start = nullptr;
    228 		  this->_M_impl._M_finish = nullptr;
    229 		  this->_M_impl._M_end_of_storage = nullptr;
    230 		}
    231 	      std::__alloc_on_copy(_M_get_Tp_allocator(),
    232 				   __x._M_get_Tp_allocator());
    233 	    }
    234 #endif
    235 	  const size_type __xlen = __x.size();
    236 	  if (__xlen > capacity())
    237 	    {
    238 	      pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
    239 						   __x.end());
    240 	      std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
    241 			    _M_get_Tp_allocator());
    242 	      _M_deallocate(this->_M_impl._M_start,
    243 			    this->_M_impl._M_end_of_storage
    244 			    - this->_M_impl._M_start);
    245 	      this->_M_impl._M_start = __tmp;
    246 	      this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
    247 	    }
    248 	  else if (size() >= __xlen)
    249 	    {
    250 	      std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
    251 			    end(), _M_get_Tp_allocator());
    252 	    }
    253 	  else
    254 	    {
    255 	      std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
    256 			this->_M_impl._M_start);
    257 	      std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
    258 					  __x._M_impl._M_finish,
    259 					  this->_M_impl._M_finish,
    260 					  _M_get_Tp_allocator());
    261 	    }
    262 	  this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
    263 	}
    264       return *this;
    265     }
    266 
    267   template<typename _Tp, typename _Alloc>
    268     _GLIBCXX20_CONSTEXPR
    269     void
    270     vector<_Tp, _Alloc>::
    271     _M_fill_assign(size_t __n, const value_type& __val)
    272     {
    273       const size_type __sz = size();
    274       if (__n > capacity())
    275 	{
    276 	  if (__n <= __sz)
    277 	    __builtin_unreachable();
    278 	  vector __tmp(__n, __val, _M_get_Tp_allocator());
    279 	  __tmp._M_impl._M_swap_data(this->_M_impl);
    280 	}
    281       else if (__n > __sz)
    282 	{
    283 	  std::fill(begin(), end(), __val);
    284 	  const size_type __add = __n - __sz;
    285 	  _GLIBCXX_ASAN_ANNOTATE_GROW(__add);
    286 	  this->_M_impl._M_finish =
    287 	    std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
    288 					  __add, __val, _M_get_Tp_allocator());
    289 	  _GLIBCXX_ASAN_ANNOTATE_GREW(__add);
    290 	}
    291       else
    292         _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
    293     }
    294 
    295   template<typename _Tp, typename _Alloc>
    296     template<typename _InputIterator>
    297       _GLIBCXX20_CONSTEXPR
    298       void
    299       vector<_Tp, _Alloc>::
    300       _M_assign_aux(_InputIterator __first, _InputIterator __last,
    301 		    std::input_iterator_tag)
    302       {
    303 	pointer __cur(this->_M_impl._M_start);
    304 	for (; __first != __last && __cur != this->_M_impl._M_finish;
    305 	     ++__cur, (void)++__first)
    306 	  *__cur = *__first;
    307 	if (__first == __last)
    308 	  _M_erase_at_end(__cur);
    309 	else
    310 	  _M_range_insert(end(), __first, __last,
    311 			  std::__iterator_category(__first));
    312       }
    313 
    314   template<typename _Tp, typename _Alloc>
    315     template<typename _ForwardIterator>
    316       _GLIBCXX20_CONSTEXPR
    317       void
    318       vector<_Tp, _Alloc>::
    319       _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
    320 		    std::forward_iterator_tag)
    321       {
    322 	const size_type __sz = size();
    323 	const size_type __len = std::distance(__first, __last);
    324 
    325 	if (__len > capacity())
    326 	  {
    327 	    if (__len <= __sz)
    328 	      __builtin_unreachable();
    329 
    330 	    _S_check_init_len(__len, _M_get_Tp_allocator());
    331 	    pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
    332 	    std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
    333 			  _M_get_Tp_allocator());
    334 	    _GLIBCXX_ASAN_ANNOTATE_REINIT;
    335 	    _M_deallocate(this->_M_impl._M_start,
    336 			  this->_M_impl._M_end_of_storage
    337 			  - this->_M_impl._M_start);
    338 	    this->_M_impl._M_start = __tmp;
    339 	    this->_M_impl._M_finish = this->_M_impl._M_start + __len;
    340 	    this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
    341 	  }
    342 	else if (__sz >= __len)
    343 	  _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
    344 	else
    345 	  {
    346 	    _ForwardIterator __mid = __first;
    347 	    std::advance(__mid, __sz);
    348 	    std::copy(__first, __mid, this->_M_impl._M_start);
    349 	    const size_type __attribute__((__unused__)) __n = __len - __sz;
    350 	    _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    351 	    this->_M_impl._M_finish =
    352 	      std::__uninitialized_copy_a(__mid, __last,
    353 					  this->_M_impl._M_finish,
    354 					  _M_get_Tp_allocator());
    355 	    _GLIBCXX_ASAN_ANNOTATE_GREW(__n);
    356 	  }
    357       }
    358 
    359 #if __cplusplus >= 201103L
    360   template<typename _Tp, typename _Alloc>
    361     _GLIBCXX20_CONSTEXPR
    362     auto
    363     vector<_Tp, _Alloc>::
    364     _M_insert_rval(const_iterator __position, value_type&& __v) -> iterator
    365     {
    366       const auto __n = __position - cbegin();
    367       if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
    368 	if (__position == cend())
    369 	  {
    370 	    _GLIBCXX_ASAN_ANNOTATE_GROW(1);
    371 	    _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    372 				     std::move(__v));
    373 	    ++this->_M_impl._M_finish;
    374 	    _GLIBCXX_ASAN_ANNOTATE_GREW(1);
    375 	  }
    376 	else
    377 	  _M_insert_aux(begin() + __n, std::move(__v));
    378       else
    379 	_M_realloc_insert(begin() + __n, std::move(__v));
    380 
    381       return iterator(this->_M_impl._M_start + __n);
    382     }
    383 
    384   template<typename _Tp, typename _Alloc>
    385     template<typename... _Args>
    386       _GLIBCXX20_CONSTEXPR
    387       auto
    388       vector<_Tp, _Alloc>::
    389       _M_emplace_aux(const_iterator __position, _Args&&... __args)
    390       -> iterator
    391       {
    392 	const auto __n = __position - cbegin();
    393 	if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
    394 	  if (__position == cend())
    395 	    {
    396 	      _GLIBCXX_ASAN_ANNOTATE_GROW(1);
    397 	      _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    398 				       std::forward<_Args>(__args)...);
    399 	      ++this->_M_impl._M_finish;
    400 	      _GLIBCXX_ASAN_ANNOTATE_GREW(1);
    401 	    }
    402 	  else
    403 	    {
    404 	      // We need to construct a temporary because something in __args...
    405 	      // could alias one of the elements of the container and so we
    406 	      // need to use it before _M_insert_aux moves elements around.
    407 	      _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
    408 	      _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
    409 	    }
    410 	else
    411 	  _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...);
    412 
    413 	return iterator(this->_M_impl._M_start + __n);
    414       }
    415 
    416   template<typename _Tp, typename _Alloc>
    417     template<typename _Arg>
    418       _GLIBCXX20_CONSTEXPR
    419       void
    420       vector<_Tp, _Alloc>::
    421       _M_insert_aux(iterator __position, _Arg&& __arg)
    422 #else
    423   template<typename _Tp, typename _Alloc>
    424     void
    425     vector<_Tp, _Alloc>::
    426     _M_insert_aux(iterator __position, const _Tp& __x)
    427 #endif
    428     {
    429       _GLIBCXX_ASAN_ANNOTATE_GROW(1);
    430       _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
    431 			       _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1)));
    432       ++this->_M_impl._M_finish;
    433       _GLIBCXX_ASAN_ANNOTATE_GREW(1);
    434 #if __cplusplus < 201103L
    435       _Tp __x_copy = __x;
    436 #endif
    437       _GLIBCXX_MOVE_BACKWARD3(__position.base(),
    438 			      this->_M_impl._M_finish - 2,
    439 			      this->_M_impl._M_finish - 1);
    440 #if __cplusplus < 201103L
    441       *__position = __x_copy;
    442 #else
    443       *__position = std::forward<_Arg>(__arg);
    444 #endif
    445     }
    446 
    447 #if __cplusplus >= 201103L
    448   template<typename _Tp, typename _Alloc>
    449     template<typename... _Args>
    450       _GLIBCXX20_CONSTEXPR
    451       void
    452       vector<_Tp, _Alloc>::
    453       _M_realloc_insert(iterator __position, _Args&&... __args)
    454 #else
    455   template<typename _Tp, typename _Alloc>
    456     void
    457     vector<_Tp, _Alloc>::
    458     _M_realloc_insert(iterator __position, const _Tp& __x)
    459 #endif
    460     {
    461       const size_type __len = _M_check_len(1u, "vector::_M_realloc_insert");
    462       if (__len <= 0)
    463 	__builtin_unreachable ();
    464       pointer __old_start = this->_M_impl._M_start;
    465       pointer __old_finish = this->_M_impl._M_finish;
    466       const size_type __elems_before = __position - begin();
    467       pointer __new_start(this->_M_allocate(__len));
    468       pointer __new_finish(__new_start);
    469 
    470       // RAII guard for allocated storage.
    471       struct _Guard
    472       {
    473 	pointer _M_storage;	    // Storage to deallocate
    474 	size_type _M_len;
    475 	_Tp_alloc_type& _M_alloc;
    476 
    477 	_GLIBCXX20_CONSTEXPR
    478 	_Guard(pointer __s, size_type __l, _Tp_alloc_type& __a)
    479 	: _M_storage(__s), _M_len(__l), _M_alloc(__a)
    480 	{ }
    481 
    482 	_GLIBCXX20_CONSTEXPR
    483 	~_Guard()
    484 	{
    485 	  if (_M_storage)
    486 	    __gnu_cxx::__alloc_traits<_Tp_alloc_type>::
    487 	      deallocate(_M_alloc, _M_storage, _M_len);
    488 	}
    489 
    490       private:
    491 	_Guard(const _Guard&);
    492       };
    493 
    494       {
    495 	_Guard __guard(__new_start, __len, _M_impl);
    496 
    497 	// The order of the three operations is dictated by the C++11
    498 	// case, where the moves could alter a new element belonging
    499 	// to the existing vector.  This is an issue only for callers
    500 	// taking the element by lvalue ref (see last bullet of C++11
    501 	// [res.on.arguments]).
    502 
    503 	// If this throws, the existing elements are unchanged.
    504 #if __cplusplus >= 201103L
    505 	_Alloc_traits::construct(this->_M_impl,
    506 				 std::__to_address(__new_start + __elems_before),
    507 				 std::forward<_Args>(__args)...);
    508 #else
    509 	_Alloc_traits::construct(this->_M_impl,
    510 				 __new_start + __elems_before,
    511 				 __x);
    512 #endif
    513 
    514 #if __cplusplus >= 201103L
    515 	if _GLIBCXX17_CONSTEXPR (_S_use_relocate())
    516 	  {
    517 	    // Relocation cannot throw.
    518 	    __new_finish = _S_relocate(__old_start, __position.base(),
    519 				       __new_start, _M_get_Tp_allocator());
    520 	    ++__new_finish;
    521 	    __new_finish = _S_relocate(__position.base(), __old_finish,
    522 				       __new_finish, _M_get_Tp_allocator());
    523 	  }
    524 	else
    525 #endif
    526 	  {
    527 	    // RAII type to destroy initialized elements.
    528 	    struct _Guard_elts
    529 	    {
    530 	      pointer _M_first, _M_last;  // Elements to destroy
    531 	      _Tp_alloc_type& _M_alloc;
    532 
    533 	      _GLIBCXX20_CONSTEXPR
    534 	      _Guard_elts(pointer __elt, _Tp_alloc_type& __a)
    535 	      : _M_first(__elt), _M_last(__elt + 1), _M_alloc(__a)
    536 	      { }
    537 
    538 	      _GLIBCXX20_CONSTEXPR
    539 	      ~_Guard_elts()
    540 	      { std::_Destroy(_M_first, _M_last, _M_alloc); }
    541 
    542 	    private:
    543 	      _Guard_elts(const _Guard_elts&);
    544 	    };
    545 
    546 	    // Guard the new element so it will be destroyed if anything throws.
    547 	    _Guard_elts __guard_elts(__new_start + __elems_before, _M_impl);
    548 
    549 	    __new_finish = std::__uninitialized_move_if_noexcept_a(
    550 			     __old_start, __position.base(),
    551 			     __new_start, _M_get_Tp_allocator());
    552 
    553 	    ++__new_finish;
    554 	    // Guard everything before the new element too.
    555 	    __guard_elts._M_first = __new_start;
    556 
    557 	    __new_finish = std::__uninitialized_move_if_noexcept_a(
    558 			      __position.base(), __old_finish,
    559 			      __new_finish, _M_get_Tp_allocator());
    560 
    561 	    // New storage has been fully initialized, destroy the old elements.
    562 	    __guard_elts._M_first = __old_start;
    563 	    __guard_elts._M_last = __old_finish;
    564 	  }
    565 	__guard._M_storage = __old_start;
    566 	__guard._M_len = this->_M_impl._M_end_of_storage - __old_start;
    567       }
    568       // deallocate should be called before assignments to _M_impl,
    569       // to avoid call-clobbering
    570 
    571       this->_M_impl._M_start = __new_start;
    572       this->_M_impl._M_finish = __new_finish;
    573       this->_M_impl._M_end_of_storage = __new_start + __len;
    574     }
    575 
    576 #if __cplusplus >= 201103L
    577   template<typename _Tp, typename _Alloc>
    578     template<typename... _Args>
    579       _GLIBCXX20_CONSTEXPR
    580       void
    581       vector<_Tp, _Alloc>::
    582       _M_realloc_append(_Args&&... __args)
    583 #else
    584   template<typename _Tp, typename _Alloc>
    585     void
    586     vector<_Tp, _Alloc>::
    587     _M_realloc_append(const _Tp& __x)
    588 #endif
    589     {
    590       const size_type __len = _M_check_len(1u, "vector::_M_realloc_append");
    591       if (__len <= 0)
    592 	__builtin_unreachable ();
    593       pointer __old_start = this->_M_impl._M_start;
    594       pointer __old_finish = this->_M_impl._M_finish;
    595       const size_type __elems = end() - begin();
    596       pointer __new_start(this->_M_allocate(__len));
    597       pointer __new_finish(__new_start);
    598 
    599       // RAII guard for allocated storage.
    600       struct _Guard
    601       {
    602 	pointer _M_storage;	    // Storage to deallocate
    603 	size_type _M_len;
    604 	_Tp_alloc_type& _M_alloc;
    605 
    606 	_GLIBCXX20_CONSTEXPR
    607 	_Guard(pointer __s, size_type __l, _Tp_alloc_type& __a)
    608 	: _M_storage(__s), _M_len(__l), _M_alloc(__a)
    609 	{ }
    610 
    611 	_GLIBCXX20_CONSTEXPR
    612 	~_Guard()
    613 	{
    614 	  if (_M_storage)
    615 	    __gnu_cxx::__alloc_traits<_Tp_alloc_type>::
    616 	      deallocate(_M_alloc, _M_storage, _M_len);
    617 	}
    618 
    619       private:
    620 	_Guard(const _Guard&);
    621       };
    622 
    623       {
    624 	_Guard __guard(__new_start, __len, _M_impl);
    625 
    626 	// The order of the three operations is dictated by the C++11
    627 	// case, where the moves could alter a new element belonging
    628 	// to the existing vector.  This is an issue only for callers
    629 	// taking the element by lvalue ref (see last bullet of C++11
    630 	// [res.on.arguments]).
    631 
    632 	// If this throws, the existing elements are unchanged.
    633 #if __cplusplus >= 201103L
    634 	_Alloc_traits::construct(this->_M_impl,
    635 				 std::__to_address(__new_start + __elems),
    636 				 std::forward<_Args>(__args)...);
    637 #else
    638 	_Alloc_traits::construct(this->_M_impl,
    639 				 __new_start + __elems,
    640 				 __x);
    641 #endif
    642 
    643 #if __cplusplus >= 201103L
    644 	if _GLIBCXX17_CONSTEXPR (_S_use_relocate())
    645 	  {
    646 	    // Relocation cannot throw.
    647 	    __new_finish = _S_relocate(__old_start, __old_finish,
    648 				       __new_start, _M_get_Tp_allocator());
    649 	    ++__new_finish;
    650 	  }
    651 	else
    652 #endif
    653 	  {
    654 	    // RAII type to destroy initialized elements.
    655 	    struct _Guard_elts
    656 	    {
    657 	      pointer _M_first, _M_last;  // Elements to destroy
    658 	      _Tp_alloc_type& _M_alloc;
    659 
    660 	      _GLIBCXX20_CONSTEXPR
    661 	      _Guard_elts(pointer __elt, _Tp_alloc_type& __a)
    662 	      : _M_first(__elt), _M_last(__elt + 1), _M_alloc(__a)
    663 	      { }
    664 
    665 	      _GLIBCXX20_CONSTEXPR
    666 	      ~_Guard_elts()
    667 	      { std::_Destroy(_M_first, _M_last, _M_alloc); }
    668 
    669 	    private:
    670 	      _Guard_elts(const _Guard_elts&);
    671 	    };
    672 
    673 	    // Guard the new element so it will be destroyed if anything throws.
    674 	    _Guard_elts __guard_elts(__new_start + __elems, _M_impl);
    675 
    676 	    __new_finish = std::__uninitialized_move_if_noexcept_a(
    677 			     __old_start, __old_finish,
    678 			     __new_start, _M_get_Tp_allocator());
    679 
    680 	    ++__new_finish;
    681 
    682 	    // New storage has been fully initialized, destroy the old elements.
    683 	    __guard_elts._M_first = __old_start;
    684 	    __guard_elts._M_last = __old_finish;
    685 	  }
    686 	__guard._M_storage = __old_start;
    687 	__guard._M_len = this->_M_impl._M_end_of_storage - __old_start;
    688       }
    689       // deallocate should be called before assignments to _M_impl,
    690       // to avoid call-clobbering
    691 
    692       this->_M_impl._M_start = __new_start;
    693       this->_M_impl._M_finish = __new_finish;
    694       this->_M_impl._M_end_of_storage = __new_start + __len;
    695     }
    696 
    697   template<typename _Tp, typename _Alloc>
    698     _GLIBCXX20_CONSTEXPR
    699     void
    700     vector<_Tp, _Alloc>::
    701     _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
    702     {
    703       if (__n != 0)
    704 	{
    705 	  if (size_type(this->_M_impl._M_end_of_storage
    706 			- this->_M_impl._M_finish) >= __n)
    707 	    {
    708 #if __cplusplus < 201103L
    709 	      value_type __x_copy = __x;
    710 #else
    711 	      _Temporary_value __tmp(this, __x);
    712 	      value_type& __x_copy = __tmp._M_val();
    713 #endif
    714 	      const size_type __elems_after = end() - __position;
    715 	      pointer __old_finish(this->_M_impl._M_finish);
    716 	      if (__elems_after > __n)
    717 		{
    718 		  _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    719 		  std::__uninitialized_move_a(__old_finish - __n,
    720 					      __old_finish,
    721 					      __old_finish,
    722 					      _M_get_Tp_allocator());
    723 		  this->_M_impl._M_finish += __n;
    724 		  _GLIBCXX_ASAN_ANNOTATE_GREW(__n);
    725 		  _GLIBCXX_MOVE_BACKWARD3(__position.base(),
    726 					  __old_finish - __n, __old_finish);
    727 		  std::fill(__position.base(), __position.base() + __n,
    728 			    __x_copy);
    729 		}
    730 	      else
    731 		{
    732 		  _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    733 		  this->_M_impl._M_finish =
    734 		    std::__uninitialized_fill_n_a(__old_finish,
    735 						  __n - __elems_after,
    736 						  __x_copy,
    737 						  _M_get_Tp_allocator());
    738 		  _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after);
    739 		  std::__uninitialized_move_a(__position.base(), __old_finish,
    740 					      this->_M_impl._M_finish,
    741 					      _M_get_Tp_allocator());
    742 		  this->_M_impl._M_finish += __elems_after;
    743 		  _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after);
    744 		  std::fill(__position.base(), __old_finish, __x_copy);
    745 		}
    746 	    }
    747 	  else
    748 	    {
    749 	      // Make local copies of these members because the compiler thinks
    750 	      // the allocator can alter them if 'this' is globally reachable.
    751 	      pointer __old_start = this->_M_impl._M_start;
    752 	      pointer __old_finish = this->_M_impl._M_finish;
    753 	      const pointer __pos = __position.base();
    754 
    755 	      const size_type __len =
    756 		_M_check_len(__n, "vector::_M_fill_insert");
    757 	      const size_type __elems_before = __pos - __old_start;
    758 	      pointer __new_start(this->_M_allocate(__len));
    759 	      pointer __new_finish(__new_start);
    760 	      __try
    761 		{
    762 		  // See _M_realloc_insert above.
    763 		  std::__uninitialized_fill_n_a(__new_start + __elems_before,
    764 						__n, __x,
    765 						_M_get_Tp_allocator());
    766 		  __new_finish = pointer();
    767 
    768 		  __new_finish
    769 		    = std::__uninitialized_move_if_noexcept_a
    770 		    (__old_start, __pos, __new_start, _M_get_Tp_allocator());
    771 
    772 		  __new_finish += __n;
    773 
    774 		  __new_finish
    775 		    = std::__uninitialized_move_if_noexcept_a
    776 		    (__pos, __old_finish, __new_finish, _M_get_Tp_allocator());
    777 		}
    778 	      __catch(...)
    779 		{
    780 		  if (!__new_finish)
    781 		    std::_Destroy(__new_start + __elems_before,
    782 				  __new_start + __elems_before + __n,
    783 				  _M_get_Tp_allocator());
    784 		  else
    785 		    std::_Destroy(__new_start, __new_finish,
    786 				  _M_get_Tp_allocator());
    787 		  _M_deallocate(__new_start, __len);
    788 		  __throw_exception_again;
    789 		}
    790 	      std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
    791 	      _GLIBCXX_ASAN_ANNOTATE_REINIT;
    792 	      _M_deallocate(__old_start,
    793 			    this->_M_impl._M_end_of_storage - __old_start);
    794 	      this->_M_impl._M_start = __new_start;
    795 	      this->_M_impl._M_finish = __new_finish;
    796 	      this->_M_impl._M_end_of_storage = __new_start + __len;
    797 	    }
    798 	}
    799     }
    800 
    801 #if __cplusplus >= 201103L
    802   template<typename _Tp, typename _Alloc>
    803     _GLIBCXX20_CONSTEXPR
    804     void
    805     vector<_Tp, _Alloc>::
    806     _M_default_append(size_type __n)
    807     {
    808       if (__n != 0)
    809 	{
    810 	  const size_type __size = size();
    811 	  size_type __navail = size_type(this->_M_impl._M_end_of_storage
    812 					 - this->_M_impl._M_finish);
    813 
    814 	  if (__size > max_size() || __navail > max_size() - __size)
    815 	    __builtin_unreachable();
    816 
    817 	  if (__navail >= __n)
    818 	    {
    819 	      if (!this->_M_impl._M_finish)
    820 		__builtin_unreachable();
    821 
    822 	      _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    823 	      this->_M_impl._M_finish =
    824 		std::__uninitialized_default_n_a(this->_M_impl._M_finish,
    825 						 __n, _M_get_Tp_allocator());
    826 	      _GLIBCXX_ASAN_ANNOTATE_GREW(__n);
    827 	    }
    828 	  else
    829 	    {
    830 	      // Make local copies of these members because the compiler thinks
    831 	      // the allocator can alter them if 'this' is globally reachable.
    832 	      pointer __old_start = this->_M_impl._M_start;
    833 	      pointer __old_finish = this->_M_impl._M_finish;
    834 
    835 	      const size_type __len =
    836 		_M_check_len(__n, "vector::_M_default_append");
    837 	      pointer __new_start(this->_M_allocate(__len));
    838 
    839 	      // RAII guard for allocated storage.
    840 	      struct _Guard
    841 	      {
    842 		pointer _M_storage;         // Storage to deallocate
    843 		size_type _M_len;
    844 		_Tp_alloc_type& _M_alloc;
    845 
    846 		_GLIBCXX20_CONSTEXPR
    847 		_Guard(pointer __s, size_type __l, _Tp_alloc_type& __a)
    848 		: _M_storage(__s), _M_len(__l), _M_alloc(__a)
    849 		{ }
    850 
    851 		_GLIBCXX20_CONSTEXPR
    852 		~_Guard()
    853 		{
    854 		  if (_M_storage)
    855 		    __gnu_cxx::__alloc_traits<_Tp_alloc_type>::
    856 		      deallocate(_M_alloc, _M_storage, _M_len);
    857 		}
    858 
    859 	      private:
    860 		_Guard(const _Guard&);
    861 	      };
    862 
    863 	      {
    864 		_Guard __guard(__new_start, __len, _M_impl);
    865 
    866 		std::__uninitialized_default_n_a(__new_start + __size, __n,
    867 						 _M_get_Tp_allocator());
    868 
    869 		if _GLIBCXX17_CONSTEXPR (_S_use_relocate())
    870 		  {
    871 		    _S_relocate(__old_start, __old_finish,
    872 				__new_start, _M_get_Tp_allocator());
    873 		  }
    874 		else
    875 		  {
    876 		    // RAII type to destroy initialized elements.
    877 		    struct _Guard_elts
    878 		    {
    879 		      pointer _M_first, _M_last;  // Elements to destroy
    880 		      _Tp_alloc_type& _M_alloc;
    881 
    882 		      _GLIBCXX20_CONSTEXPR
    883 		      _Guard_elts(pointer __first, size_type __n,
    884 				  _Tp_alloc_type& __a)
    885 		      : _M_first(__first), _M_last(__first + __n), _M_alloc(__a)
    886 		      { }
    887 
    888 		      _GLIBCXX20_CONSTEXPR
    889 		      ~_Guard_elts()
    890 		      { std::_Destroy(_M_first, _M_last, _M_alloc); }
    891 
    892 		    private:
    893 		      _Guard_elts(const _Guard_elts&);
    894 		    };
    895 		    _Guard_elts __guard_elts(__new_start + __size, __n, _M_impl);
    896 
    897 		    std::__uninitialized_move_if_noexcept_a(
    898 		      __old_start, __old_finish, __new_start,
    899 		      _M_get_Tp_allocator());
    900 
    901 		    __guard_elts._M_first = __old_start;
    902 		    __guard_elts._M_last = __old_finish;
    903 		  }
    904 		_GLIBCXX_ASAN_ANNOTATE_REINIT;
    905 		__guard._M_storage = __old_start;
    906 		__guard._M_len = this->_M_impl._M_end_of_storage - __old_start;
    907 	      }
    908 	      // deallocate should be called before assignments to _M_impl,
    909 	      // to avoid call-clobbering
    910 
    911 	      this->_M_impl._M_start = __new_start;
    912 	      this->_M_impl._M_finish = __new_start + __size + __n;
    913 	      this->_M_impl._M_end_of_storage = __new_start + __len;
    914 	    }
    915 	}
    916     }
    917 
    918   template<typename _Tp, typename _Alloc>
    919     _GLIBCXX20_CONSTEXPR
    920     bool
    921     vector<_Tp, _Alloc>::
    922     _M_shrink_to_fit()
    923     {
    924       if (capacity() == size())
    925 	return false;
    926       _GLIBCXX_ASAN_ANNOTATE_REINIT;
    927       return std::__shrink_to_fit_aux<vector>::_S_do_it(*this);
    928     }
    929 #endif
    930 
    931   template<typename _Tp, typename _Alloc>
    932     template<typename _InputIterator>
    933       _GLIBCXX20_CONSTEXPR
    934       void
    935       vector<_Tp, _Alloc>::
    936       _M_range_insert(iterator __pos, _InputIterator __first,
    937 		      _InputIterator __last, std::input_iterator_tag)
    938       {
    939 	if (__pos == end())
    940 	  {
    941 	    for (; __first != __last; ++__first)
    942 	      insert(end(), *__first);
    943 	  }
    944 	else if (__first != __last)
    945 	  {
    946 	    vector __tmp(__first, __last, _M_get_Tp_allocator());
    947 	    insert(__pos,
    948 		   _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.begin()),
    949 		   _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.end()));
    950 	  }
    951       }
    952 
    953   template<typename _Tp, typename _Alloc>
    954     template<typename _ForwardIterator>
    955       _GLIBCXX20_CONSTEXPR
    956       void
    957       vector<_Tp, _Alloc>::
    958       _M_range_insert(iterator __position, _ForwardIterator __first,
    959 		      _ForwardIterator __last, std::forward_iterator_tag)
    960       {
    961 	if (__first != __last)
    962 	  {
    963 	    const size_type __n = std::distance(__first, __last);
    964 	    if (size_type(this->_M_impl._M_end_of_storage
    965 			  - this->_M_impl._M_finish) >= __n)
    966 	      {
    967 		const size_type __elems_after = end() - __position;
    968 		pointer __old_finish(this->_M_impl._M_finish);
    969 		if (__elems_after > __n)
    970 		  {
    971 		    _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    972 		    std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
    973 						this->_M_impl._M_finish,
    974 						this->_M_impl._M_finish,
    975 						_M_get_Tp_allocator());
    976 		    this->_M_impl._M_finish += __n;
    977 		    _GLIBCXX_ASAN_ANNOTATE_GREW(__n);
    978 		    _GLIBCXX_MOVE_BACKWARD3(__position.base(),
    979 					    __old_finish - __n, __old_finish);
    980 		    std::copy(__first, __last, __position);
    981 		  }
    982 		else
    983 		  {
    984 		    _ForwardIterator __mid = __first;
    985 		    std::advance(__mid, __elems_after);
    986 		    _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
    987 		    std::__uninitialized_copy_a(__mid, __last,
    988 						this->_M_impl._M_finish,
    989 						_M_get_Tp_allocator());
    990 		    this->_M_impl._M_finish += __n - __elems_after;
    991 		    _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after);
    992 		    std::__uninitialized_move_a(__position.base(),
    993 						__old_finish,
    994 						this->_M_impl._M_finish,
    995 						_M_get_Tp_allocator());
    996 		    this->_M_impl._M_finish += __elems_after;
    997 		    _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after);
    998 		    std::copy(__first, __mid, __position);
    999 		  }
   1000 	      }
   1001 	    else
   1002 	      {
   1003 		// Make local copies of these members because the compiler
   1004 		// thinks the allocator can alter them if 'this' is globally
   1005 		// reachable.
   1006 		pointer __old_start = this->_M_impl._M_start;
   1007 		pointer __old_finish = this->_M_impl._M_finish;
   1008 		if ((__old_finish - __old_start) < 0)
   1009 		  __builtin_unreachable();
   1010 
   1011 		const size_type __len =
   1012 		  _M_check_len(__n, "vector::_M_range_insert");
   1013 #if __cplusplus < 201103L
   1014 		if (__len < (__n + (__old_finish - __old_start)))
   1015 		  __builtin_unreachable();
   1016 #endif
   1017 
   1018 		pointer __new_start(this->_M_allocate(__len));
   1019 		pointer __new_finish(__new_start);
   1020 		__try
   1021 		  {
   1022 		    __new_finish
   1023 		      = std::__uninitialized_move_if_noexcept_a
   1024 		      (__old_start, __position.base(),
   1025 		       __new_start, _M_get_Tp_allocator());
   1026 		    __new_finish
   1027 		      = std::__uninitialized_copy_a(__first, __last,
   1028 						    __new_finish,
   1029 						    _M_get_Tp_allocator());
   1030 		    __new_finish
   1031 		      = std::__uninitialized_move_if_noexcept_a
   1032 		      (__position.base(), __old_finish,
   1033 		       __new_finish, _M_get_Tp_allocator());
   1034 		  }
   1035 		__catch(...)
   1036 		  {
   1037 		    std::_Destroy(__new_start, __new_finish,
   1038 				  _M_get_Tp_allocator());
   1039 		    _M_deallocate(__new_start, __len);
   1040 		    __throw_exception_again;
   1041 		  }
   1042 		std::_Destroy(__old_start, __old_finish,
   1043 			      _M_get_Tp_allocator());
   1044 		_GLIBCXX_ASAN_ANNOTATE_REINIT;
   1045 		_M_deallocate(__old_start,
   1046 			      this->_M_impl._M_end_of_storage - __old_start);
   1047 		this->_M_impl._M_start = __new_start;
   1048 		this->_M_impl._M_finish = __new_finish;
   1049 		this->_M_impl._M_end_of_storage = __new_start + __len;
   1050 	      }
   1051 	  }
   1052       }
   1053 
   1054 
   1055   // vector<bool>
   1056   template<typename _Alloc>
   1057     _GLIBCXX20_CONSTEXPR
   1058     void
   1059     vector<bool, _Alloc>::
   1060     _M_reallocate(size_type __n)
   1061     {
   1062       const iterator __begin = begin(), __end = end();
   1063       if (size_type(__end - __begin) > __n)
   1064 	__builtin_unreachable();
   1065       _Bit_pointer __q = this->_M_allocate(__n);
   1066       iterator __start(std::__addressof(*__q), 0);
   1067       iterator __finish(_M_copy_aligned(__begin, __end, __start));
   1068       this->_M_deallocate();
   1069       this->_M_impl._M_start = __start;
   1070       this->_M_impl._M_finish = __finish;
   1071       this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
   1072     }
   1073 
   1074   template<typename _Alloc>
   1075     _GLIBCXX20_CONSTEXPR
   1076     void
   1077     vector<bool, _Alloc>::
   1078     _M_fill_insert(iterator __position, size_type __n, bool __x)
   1079     {
   1080       if (__n == 0)
   1081 	return;
   1082       if (capacity() - size() >= __n)
   1083 	{
   1084 	  std::copy_backward(__position, end(),
   1085 			     this->_M_impl._M_finish + difference_type(__n));
   1086 	  std::fill(__position, __position + difference_type(__n), __x);
   1087 	  this->_M_impl._M_finish += difference_type(__n);
   1088 	}
   1089       else
   1090 	{
   1091 	  const size_type __len = 
   1092 	    _M_check_len(__n, "vector<bool>::_M_fill_insert");
   1093 	  iterator __begin = begin(), __end = end();
   1094 	  _Bit_pointer __q = this->_M_allocate(__len);
   1095 	  iterator __start(std::__addressof(*__q), 0);
   1096 	  iterator __i = _M_copy_aligned(__begin, __position, __start);
   1097 	  std::fill(__i, __i + difference_type(__n), __x);
   1098 	  iterator __finish = std::copy(__position, __end,
   1099 					__i + difference_type(__n));
   1100 	  this->_M_deallocate();
   1101 	  this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
   1102 	  this->_M_impl._M_start = __start;
   1103 	  this->_M_impl._M_finish = __finish;
   1104 	}
   1105     }
   1106 
   1107   template<typename _Alloc>
   1108     template<typename _ForwardIterator>
   1109       _GLIBCXX20_CONSTEXPR
   1110       void
   1111       vector<bool, _Alloc>::
   1112       _M_insert_range(iterator __position, _ForwardIterator __first, 
   1113 		      _ForwardIterator __last, std::forward_iterator_tag)
   1114       {
   1115 	if (__first != __last)
   1116 	  {
   1117 	    size_type __n = std::distance(__first, __last);
   1118 	    if (capacity() - size() >= __n)
   1119 	      {
   1120 		std::copy_backward(__position, end(),
   1121 				   this->_M_impl._M_finish
   1122 				   + difference_type(__n));
   1123 		std::copy(__first, __last, __position);
   1124 		this->_M_impl._M_finish += difference_type(__n);
   1125 	      }
   1126 	    else
   1127 	      {
   1128 		const size_type __len =
   1129 		  _M_check_len(__n, "vector<bool>::_M_insert_range");
   1130 		const iterator __begin = begin(), __end = end();
   1131 		_Bit_pointer __q = this->_M_allocate(__len);
   1132 		iterator __start(std::__addressof(*__q), 0);
   1133 		iterator __i = _M_copy_aligned(__begin, __position, __start);
   1134 		__i = std::copy(__first, __last, __i);
   1135 		iterator __finish = std::copy(__position, __end, __i);
   1136 		this->_M_deallocate();
   1137 		this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
   1138 		this->_M_impl._M_start = __start;
   1139 		this->_M_impl._M_finish = __finish;
   1140 	      }
   1141 	  }
   1142       }
   1143 
   1144   template<typename _Alloc>
   1145     _GLIBCXX20_CONSTEXPR
   1146     void
   1147     vector<bool, _Alloc>::
   1148     _M_insert_aux(iterator __position, bool __x)
   1149     {
   1150       if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
   1151 	{
   1152 	  std::copy_backward(__position, this->_M_impl._M_finish, 
   1153 			     this->_M_impl._M_finish + 1);
   1154 	  *__position = __x;
   1155 	  ++this->_M_impl._M_finish;
   1156 	}
   1157       else
   1158 	{
   1159 	  const size_type __len =
   1160 	    _M_check_len(size_type(1), "vector<bool>::_M_insert_aux");
   1161 	  _Bit_pointer __q = this->_M_allocate(__len);
   1162 	  iterator __start(std::__addressof(*__q), 0);
   1163 	  iterator __i = _M_copy_aligned(begin(), __position, __start);
   1164 	  *__i++ = __x;
   1165 	  iterator __finish = std::copy(__position, end(), __i);
   1166 	  this->_M_deallocate();
   1167 	  this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
   1168 	  this->_M_impl._M_start = __start;
   1169 	  this->_M_impl._M_finish = __finish;
   1170 	}
   1171     }
   1172 
   1173   template<typename _Alloc>
   1174     _GLIBCXX20_CONSTEXPR
   1175     typename vector<bool, _Alloc>::iterator
   1176     vector<bool, _Alloc>::
   1177     _M_erase(iterator __position)
   1178     {
   1179       if (__position + 1 != end())
   1180         std::copy(__position + 1, end(), __position);
   1181       --this->_M_impl._M_finish;
   1182       return __position;
   1183     }
   1184 
   1185   template<typename _Alloc>
   1186     _GLIBCXX20_CONSTEXPR
   1187     typename vector<bool, _Alloc>::iterator
   1188     vector<bool, _Alloc>::
   1189     _M_erase(iterator __first, iterator __last)
   1190     {
   1191       if (__first != __last)
   1192 	_M_erase_at_end(std::copy(__last, end(), __first));
   1193       return __first;
   1194     }
   1195 
   1196 #if __cplusplus >= 201103L
   1197   template<typename _Alloc>
   1198     _GLIBCXX20_CONSTEXPR
   1199     bool
   1200     vector<bool, _Alloc>::
   1201     _M_shrink_to_fit()
   1202     {
   1203       if (capacity() - size() < int(_S_word_bit))
   1204 	return false;
   1205       __try
   1206 	{
   1207 	  if (size_type __n = size())
   1208 	    _M_reallocate(__n);
   1209 	  else
   1210 	    {
   1211 	      this->_M_deallocate();
   1212 	      this->_M_impl._M_reset();
   1213 	    }
   1214 	  return true;
   1215 	}
   1216       __catch(...)
   1217 	{ return false; }
   1218     }
   1219 #endif
   1220 
   1221 _GLIBCXX_END_NAMESPACE_CONTAINER
   1222 _GLIBCXX_END_NAMESPACE_VERSION
   1223 } // namespace std
   1224 
   1225 #if __cplusplus >= 201103L
   1226 
   1227 namespace std _GLIBCXX_VISIBILITY(default)
   1228 {
   1229 _GLIBCXX_BEGIN_NAMESPACE_VERSION
   1230 
   1231   template<typename _Alloc>
   1232     size_t
   1233     hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>::
   1234     operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const noexcept
   1235     {
   1236       size_t __hash = 0;
   1237       const size_t __words = __b.size() / _S_word_bit;
   1238       if (__words)
   1239 	{
   1240 	  const size_t __clength = __words * sizeof(_Bit_type);
   1241 	  __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength);
   1242 	}
   1243 
   1244       const size_t __extrabits = __b.size() % _S_word_bit;
   1245       if (__extrabits)
   1246 	{
   1247 	  _Bit_type __hiword = *__b._M_impl._M_finish._M_p;
   1248 	  __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits);
   1249 
   1250 	  const size_t __clength
   1251 	    = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__;
   1252 	  if (__words)
   1253 	    __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash);
   1254 	  else
   1255 	    __hash = std::_Hash_impl::hash(&__hiword, __clength);
   1256 	}
   1257 
   1258       return __hash;
   1259     }
   1260 
   1261 _GLIBCXX_END_NAMESPACE_VERSION
   1262 } // namespace std
   1263 
   1264 #endif // C++11
   1265 
   1266 #undef _GLIBCXX_ASAN_ANNOTATE_REINIT
   1267 #undef _GLIBCXX_ASAN_ANNOTATE_GROW
   1268 #undef _GLIBCXX_ASAN_ANNOTATE_GREW
   1269 #undef _GLIBCXX_ASAN_ANNOTATE_SHRINK
   1270 
   1271 #endif /* _VECTOR_TCC */
   1272