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