Daily bump.
[official-gcc.git] / libstdc++-v3 / include / debug / vector
blob216822975a2f95abe5c6085a994ea331281c75af
1 // Debugging vector implementation -*- C++ -*-
3 // Copyright (C) 2003-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.
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.
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.
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/>.
25 /** @file debug/vector
26  *  This file is a GNU debug extension to the Standard C++ Library.
27  */
29 #ifndef _GLIBCXX_DEBUG_VECTOR
30 #define _GLIBCXX_DEBUG_VECTOR 1
32 #pragma GCC system_header
34 #include <bits/c++config.h>
35 namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
36   template<typename _Tp, typename _Allocator> class vector;
37 } } // namespace std::__debug
39 #include <vector>
40 #include <debug/safe_sequence.h>
41 #include <debug/safe_container.h>
42 #include <debug/safe_iterator.h>
44 namespace __gnu_debug
46   /** @brief Base class for Debug Mode vector.
47    *
48    * Adds information about the guaranteed capacity, which is useful for
49    * detecting code which relies on non-portable implementation details of
50    * the libstdc++ reallocation policy.
51    */
52   template<typename _SafeSequence,
53            typename _BaseSequence>
54     class _Safe_vector
55     {
56       typedef typename _BaseSequence::size_type size_type;
58       _GLIBCXX20_CONSTEXPR
59       const _SafeSequence&
60       _M_seq() const { return *static_cast<const _SafeSequence*>(this); }
62     protected:
63       _GLIBCXX20_CONSTEXPR
64       _Safe_vector() _GLIBCXX_NOEXCEPT
65         : _M_guaranteed_capacity(0)
66       { _M_update_guaranteed_capacity(); }
68       _GLIBCXX20_CONSTEXPR
69       _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
70         : _M_guaranteed_capacity(0)
71       { _M_update_guaranteed_capacity(); }
73       _GLIBCXX20_CONSTEXPR
74       _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
75         : _M_guaranteed_capacity(__n)
76       { }
78       _GLIBCXX20_CONSTEXPR
79       _Safe_vector&
80       operator=(const _Safe_vector&) _GLIBCXX_NOEXCEPT
81       {
82         _M_update_guaranteed_capacity();
83         return *this;
84       }
86 #if __cplusplus >= 201103L
87       _GLIBCXX20_CONSTEXPR
88       _Safe_vector(_Safe_vector&& __x) noexcept
89         : _Safe_vector()
90       { __x._M_guaranteed_capacity = 0; }
92       _GLIBCXX20_CONSTEXPR
93       _Safe_vector&
94       operator=(_Safe_vector&& __x) noexcept
95       {
96         _M_update_guaranteed_capacity();
97         __x._M_guaranteed_capacity = 0;
98         return *this;
99       }
100 #endif
102       size_type _M_guaranteed_capacity;
104       bool
105       _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
106       { return __elements > _M_seq().capacity(); }
108       _GLIBCXX20_CONSTEXPR
109       void
110       _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
111       {
112         if (_M_seq().size() > _M_guaranteed_capacity)
113           _M_guaranteed_capacity = _M_seq().size();
114       }
115     };
118 namespace std _GLIBCXX_VISIBILITY(default)
120 namespace __debug
122   /// Class std::vector with safety/checking/debug instrumentation.
123   template<typename _Tp,
124            typename _Allocator = std::allocator<_Tp> >
125     class vector
126     : public __gnu_debug::_Safe_container<
127         vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
128       public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
129       public __gnu_debug::_Safe_vector<
130         vector<_Tp, _Allocator>,
131         _GLIBCXX_STD_C::vector<_Tp, _Allocator> >
132     {
133       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>           _Base;
134       typedef __gnu_debug::_Safe_container<
135         vector, _Allocator, __gnu_debug::_Safe_sequence>        _Safe;
136       typedef __gnu_debug::_Safe_vector<vector, _Base>          _Safe_vector;
138       typedef typename _Base::iterator          _Base_iterator;
139       typedef typename _Base::const_iterator    _Base_const_iterator;
140       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
142       template<typename _ItT, typename _SeqT, typename _CatT>
143         friend class ::__gnu_debug::_Safe_iterator;
145       // Reference wrapper for base class. Disambiguates vector(const _Base&)
146       // from copy constructor by requiring a user-defined conversion.
147       // See PR libstdc++/90102.
148       struct _Base_ref
149       {
150         _Base_ref(const _Base& __r) : _M_ref(__r) { }
152         const _Base& _M_ref;
153       };
155     public:
156       typedef typename _Base::reference                 reference;
157       typedef typename _Base::const_reference           const_reference;
159       typedef __gnu_debug::_Safe_iterator<
160         _Base_iterator, vector>                         iterator;
161       typedef __gnu_debug::_Safe_iterator<
162         _Base_const_iterator, vector>                   const_iterator;
164       typedef typename _Base::size_type                 size_type;
165       typedef typename _Base::difference_type           difference_type;
167       typedef _Tp                                       value_type;
168       typedef _Allocator                                allocator_type;
169       typedef typename _Base::pointer                   pointer;
170       typedef typename _Base::const_pointer             const_pointer;
171       typedef std::reverse_iterator<iterator>           reverse_iterator;
172       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
174       // 23.2.4.1 construct/copy/destroy:
176 #if __cplusplus < 201103L
177       vector() _GLIBCXX_NOEXCEPT
178       : _Base() { }
179 #else
180       vector() = default;
181 #endif
183       _GLIBCXX20_CONSTEXPR
184       explicit
185       vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
186       : _Base(__a) { }
188 #if __cplusplus >= 201103L
189       _GLIBCXX20_CONSTEXPR
190       explicit
191       vector(size_type __n, const _Allocator& __a = _Allocator())
192       : _Base(__n, __a), _Safe_vector(__n) { }
194       _GLIBCXX20_CONSTEXPR
195       vector(size_type __n, const __type_identity_t<_Tp>& __value,
196              const _Allocator& __a = _Allocator())
197       : _Base(__n, __value, __a) { }
198 #else
199       explicit
200       vector(size_type __n, const _Tp& __value = _Tp(),
201              const _Allocator& __a = _Allocator())
202       : _Base(__n, __value, __a) { }
203 #endif
205 #if __cplusplus >= 201103L
206       template<class _InputIterator,
207                typename = std::_RequireInputIter<_InputIterator>>
208 #else
209       template<class _InputIterator>
210 #endif
211         _GLIBCXX20_CONSTEXPR
212         vector(_InputIterator __first, _InputIterator __last,
213                const _Allocator& __a = _Allocator())
214         : _Base(__gnu_debug::__base(std::__is_constant_evaluated() ? __first
215                   : __glibcxx_check_valid_constructor_range(__first, __last)),
216                 __gnu_debug::__base(__last), __a) { }
218 #if __cplusplus < 201103L
219       vector(const vector& __x)
220       : _Base(__x) { }
222       ~vector() _GLIBCXX_NOEXCEPT { }
223 #else
224       vector(const vector&) = default;
225       vector(vector&&) = default;
227       _GLIBCXX20_CONSTEXPR
228       vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
229       : _Base(__x, __a) { }
231       _GLIBCXX20_CONSTEXPR
232       vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
233       noexcept(
234         std::is_nothrow_constructible<_Base,
235           _Base, const allocator_type&>::value )
236       : _Safe(std::move(__x), __a),
237         _Base(std::move(__x), __a),
238         _Safe_vector(std::move(__x)) { }
240       _GLIBCXX20_CONSTEXPR
241       vector(initializer_list<value_type> __l,
242              const allocator_type& __a = allocator_type())
243       : _Base(__l, __a) { }
245       ~vector() = default;
246 #endif
248       /// Construction from a normal-mode vector
249       _GLIBCXX20_CONSTEXPR
250       vector(_Base_ref __x)
251       : _Base(__x._M_ref) { }
253 #if __cplusplus >= 201103L
254       vector&
255       operator=(const vector&) = default;
257       vector&
258       operator=(vector&&) = default;
260       _GLIBCXX20_CONSTEXPR
261       vector&
262       operator=(initializer_list<value_type> __l)
263       {
264         _Base::operator=(__l);
265         if (!std::__is_constant_evaluated())
266           {
267             this->_M_invalidate_all();
268             this->_M_update_guaranteed_capacity();
269           }
270         return *this;
271       }
272 #endif
274 #if __cplusplus >= 201103L
275       template<typename _InputIterator,
276                typename = std::_RequireInputIter<_InputIterator>>
277 #else
278       template<typename _InputIterator>
279 #endif
280         _GLIBCXX20_CONSTEXPR
281         void
282         assign(_InputIterator __first, _InputIterator __last)
283         {
284           if (std::__is_constant_evaluated())
285             return _Base::assign(__gnu_debug::__unsafe(__first),
286                                  __gnu_debug::__unsafe(__last));
288           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
289           __glibcxx_check_valid_range2(__first, __last, __dist);
291           if (__dist.second >= __gnu_debug::__dp_sign)
292             _Base::assign(__gnu_debug::__unsafe(__first),
293                           __gnu_debug::__unsafe(__last));
294           else
295             _Base::assign(__first, __last);
297           this->_M_invalidate_all();
298           this->_M_update_guaranteed_capacity();
299         }
301       _GLIBCXX20_CONSTEXPR
302       void
303       assign(size_type __n, const _Tp& __u)
304       {
305         _Base::assign(__n, __u);
306         if (!std::__is_constant_evaluated())
307           {
308             this->_M_invalidate_all();
309             this->_M_update_guaranteed_capacity();
310           }
311       }
313 #if __cplusplus >= 201103L
314       _GLIBCXX20_CONSTEXPR
315       void
316       assign(initializer_list<value_type> __l)
317       {
318         _Base::assign(__l);
319         if (!std::__is_constant_evaluated())
320           {
321             this->_M_invalidate_all();
322             this->_M_update_guaranteed_capacity();
323           }
324       }
325 #endif
327       using _Base::get_allocator;
329       // iterators:
330       _GLIBCXX_NODISCARD
331       _GLIBCXX20_CONSTEXPR
332       iterator
333       begin() _GLIBCXX_NOEXCEPT
334       { return iterator(_Base::begin(), this); }
336       _GLIBCXX_NODISCARD
337       _GLIBCXX20_CONSTEXPR
338       const_iterator
339       begin() const _GLIBCXX_NOEXCEPT
340       { return const_iterator(_Base::begin(), this); }
342       _GLIBCXX_NODISCARD
343       _GLIBCXX20_CONSTEXPR
344       iterator
345       end() _GLIBCXX_NOEXCEPT
346       { return iterator(_Base::end(), this); }
348       _GLIBCXX_NODISCARD
349       _GLIBCXX20_CONSTEXPR
350       const_iterator
351       end() const _GLIBCXX_NOEXCEPT
352       { return const_iterator(_Base::end(), this); }
354       _GLIBCXX_NODISCARD
355       _GLIBCXX20_CONSTEXPR
356       reverse_iterator
357       rbegin() _GLIBCXX_NOEXCEPT
358       { return reverse_iterator(end()); }
360       _GLIBCXX_NODISCARD
361       _GLIBCXX20_CONSTEXPR
362       const_reverse_iterator
363       rbegin() const _GLIBCXX_NOEXCEPT
364       { return const_reverse_iterator(end()); }
366       _GLIBCXX_NODISCARD
367       _GLIBCXX20_CONSTEXPR
368       reverse_iterator
369       rend() _GLIBCXX_NOEXCEPT
370       { return reverse_iterator(begin()); }
372       _GLIBCXX_NODISCARD
373       _GLIBCXX20_CONSTEXPR
374       const_reverse_iterator
375       rend() const _GLIBCXX_NOEXCEPT
376       { return const_reverse_iterator(begin()); }
378 #if __cplusplus >= 201103L
379       [[__nodiscard__]]
380       _GLIBCXX20_CONSTEXPR
381       const_iterator
382       cbegin() const noexcept
383       { return const_iterator(_Base::begin(), this); }
385       [[__nodiscard__]]
386       _GLIBCXX20_CONSTEXPR
387       const_iterator
388       cend() const noexcept
389       { return const_iterator(_Base::end(), this); }
391       [[__nodiscard__]]
392       _GLIBCXX20_CONSTEXPR
393       const_reverse_iterator
394       crbegin() const noexcept
395       { return const_reverse_iterator(end()); }
397       [[__nodiscard__]]
398       _GLIBCXX20_CONSTEXPR
399       const_reverse_iterator
400       crend() const noexcept
401       { return const_reverse_iterator(begin()); }
402 #endif
404       // 23.2.4.2 capacity:
405       using _Base::size;
406       using _Base::max_size;
408 #if __cplusplus >= 201103L
409       _GLIBCXX20_CONSTEXPR
410       void
411       resize(size_type __sz)
412       {
413         if (std::__is_constant_evaluated())
414           return _Base::resize(__sz);
416         bool __realloc = this->_M_requires_reallocation(__sz);
417         if (__sz < this->size())
418           this->_M_invalidate_after_nth(__sz);
419         _Base::resize(__sz);
420         if (__realloc)
421           this->_M_invalidate_all();
422         this->_M_update_guaranteed_capacity();
423       }
425       _GLIBCXX20_CONSTEXPR
426       void
427       resize(size_type __sz, const _Tp& __c)
428       {
429         if (std::__is_constant_evaluated())
430           return _Base::resize(__sz, __c);
432         bool __realloc = this->_M_requires_reallocation(__sz);
433         if (__sz < this->size())
434           this->_M_invalidate_after_nth(__sz);
435         _Base::resize(__sz, __c);
436         if (__realloc)
437           this->_M_invalidate_all();
438         this->_M_update_guaranteed_capacity();
439       }
440 #else
441       void
442       resize(size_type __sz, _Tp __c = _Tp())
443       {
444         bool __realloc = this->_M_requires_reallocation(__sz);
445         if (__sz < this->size())
446           this->_M_invalidate_after_nth(__sz);
447         _Base::resize(__sz, __c);
448         if (__realloc)
449           this->_M_invalidate_all();
450         this->_M_update_guaranteed_capacity();
451       }
452 #endif
454 #if __cplusplus >= 201103L
455       _GLIBCXX20_CONSTEXPR
456       void
457       shrink_to_fit()
458       {
459         if (std::__is_constant_evaluated())
460           return _Base::shrink_to_fit();
462         if (_Base::_M_shrink_to_fit())
463           {
464             this->_M_guaranteed_capacity = _Base::capacity();
465             this->_M_invalidate_all();
466           }
467       }
468 #endif
470       _GLIBCXX_NODISCARD
471       _GLIBCXX20_CONSTEXPR
472       size_type
473       capacity() const _GLIBCXX_NOEXCEPT
474       {
475         if (std::__is_constant_evaluated())
476           return _Base::capacity();
478 #ifdef _GLIBCXX_DEBUG_PEDANTIC
479         return this->_M_guaranteed_capacity;
480 #else
481         return _Base::capacity();
482 #endif
483       }
485       using _Base::empty;
487       _GLIBCXX20_CONSTEXPR
488       void
489       reserve(size_type __n)
490       {
491         if (std::__is_constant_evaluated())
492           return _Base::reserve(__n);
494         bool __realloc = this->_M_requires_reallocation(__n);
495         _Base::reserve(__n);
496         if (__n > this->_M_guaranteed_capacity)
497           this->_M_guaranteed_capacity = __n;
498         if (__realloc)
499           this->_M_invalidate_all();
500       }
502       // element access:
503       _GLIBCXX_NODISCARD
504       _GLIBCXX20_CONSTEXPR
505       reference
506       operator[](size_type __n) _GLIBCXX_NOEXCEPT
507       {
508         __glibcxx_check_subscript(__n);
509         return _Base::operator[](__n);
510       }
512       _GLIBCXX_NODISCARD
513       _GLIBCXX20_CONSTEXPR
514       const_reference
515       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
516       {
517         __glibcxx_check_subscript(__n);
518         return _Base::operator[](__n);
519       }
521       using _Base::at;
523       _GLIBCXX_NODISCARD
524       _GLIBCXX20_CONSTEXPR
525       reference
526       front() _GLIBCXX_NOEXCEPT
527       {
528         __glibcxx_check_nonempty();
529         return _Base::front();
530       }
532       _GLIBCXX_NODISCARD
533       _GLIBCXX20_CONSTEXPR
534       const_reference
535       front() const _GLIBCXX_NOEXCEPT
536       {
537         __glibcxx_check_nonempty();
538         return _Base::front();
539       }
541       _GLIBCXX_NODISCARD
542       _GLIBCXX20_CONSTEXPR
543       reference
544       back() _GLIBCXX_NOEXCEPT
545       {
546         __glibcxx_check_nonempty();
547         return _Base::back();
548       }
550       _GLIBCXX_NODISCARD
551       _GLIBCXX20_CONSTEXPR
552       const_reference
553       back() const _GLIBCXX_NOEXCEPT
554       {
555         __glibcxx_check_nonempty();
556         return _Base::back();
557       }
559       // _GLIBCXX_RESOLVE_LIB_DEFECTS
560       // DR 464. Suggestion for new member functions in standard containers.
561       using _Base::data;
563       // 23.2.4.3 modifiers:
564       _GLIBCXX20_CONSTEXPR
565       void
566       push_back(const _Tp& __x)
567       {
568         if (std::__is_constant_evaluated())
569           return _Base::push_back(__x);
571         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
572         _Base::push_back(__x);
573         if (__realloc)
574           this->_M_invalidate_all();
575         this->_M_update_guaranteed_capacity();
576       }
578 #if __cplusplus >= 201103L
579       template<typename _Up = _Tp>
580         _GLIBCXX20_CONSTEXPR
581         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
582                                         void>::__type
583         push_back(_Tp&& __x)
584         { emplace_back(std::move(__x)); }
586       template<typename... _Args>
587         _GLIBCXX20_CONSTEXPR
588 #if __cplusplus > 201402L
589         reference
590 #else
591         void
592 #endif
593         emplace_back(_Args&&... __args)
594         {
595           if (std::__is_constant_evaluated())
596             return _Base::emplace_back(std::forward<_Args>(__args)...);
598           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
599           _Base::emplace_back(std::forward<_Args>(__args)...);
600           if (__realloc)
601             this->_M_invalidate_all();
602           this->_M_update_guaranteed_capacity();
603 #if __cplusplus > 201402L
604           return back();
605 #endif
606         }
607 #endif
609       _GLIBCXX20_CONSTEXPR
610       void
611       pop_back() _GLIBCXX_NOEXCEPT
612       {
613         if (!std::__is_constant_evaluated())
614           {
615             __glibcxx_check_nonempty();
616             this->_M_invalidate_if(_Equal(--_Base::end()));
617           }
618         _Base::pop_back();
619       }
621 #if __cplusplus >= 201103L
622       template<typename... _Args>
623         _GLIBCXX20_CONSTEXPR
624         iterator
625         emplace(const_iterator __position, _Args&&... __args)
626         {
627           if (std::__is_constant_evaluated())
628             return iterator(_Base::emplace(__position.base(),
629                                            std::forward<_Args>(__args)...),
630                             this);
632           __glibcxx_check_insert(__position);
633           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
634           difference_type __offset = __position.base() - _Base::cbegin();
635           _Base_iterator __res = _Base::emplace(__position.base(),
636                                                 std::forward<_Args>(__args)...);
637           if (__realloc)
638             this->_M_invalidate_all();
639           else
640             this->_M_invalidate_after_nth(__offset);
641           this->_M_update_guaranteed_capacity();
642           return { __res, this };
643         }
644 #endif
646       _GLIBCXX20_CONSTEXPR
647       iterator
648 #if __cplusplus >= 201103L
649       insert(const_iterator __position, const _Tp& __x)
650 #else
651       insert(iterator __position, const _Tp& __x)
652 #endif
653       {
654         if (std::__is_constant_evaluated())
655           return iterator(_Base::insert(__position.base(), __x), this);
657         __glibcxx_check_insert(__position);
658         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
659         difference_type __offset = __position.base() - _Base::begin();
660         _Base_iterator __res = _Base::insert(__position.base(), __x);
661         if (__realloc)
662           this->_M_invalidate_all();
663         else
664           this->_M_invalidate_after_nth(__offset);
665         this->_M_update_guaranteed_capacity();
666         return iterator(__res, this);
667       }
669 #if __cplusplus >= 201103L
670       template<typename _Up = _Tp>
671         _GLIBCXX20_CONSTEXPR
672         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
673                                         iterator>::__type
674         insert(const_iterator __position, _Tp&& __x)
675         { return emplace(__position, std::move(__x)); }
677       _GLIBCXX20_CONSTEXPR
678       iterator
679       insert(const_iterator __position, initializer_list<value_type> __l)
680       { return this->insert(__position, __l.begin(), __l.end()); }
681 #endif
683 #if __cplusplus >= 201103L
684       _GLIBCXX20_CONSTEXPR
685       iterator
686       insert(const_iterator __position, size_type __n, const _Tp& __x)
687       {
688         if (std::__is_constant_evaluated())
689           return iterator(_Base::insert(__position.base(), __n, __x), this);
691         __glibcxx_check_insert(__position);
692         bool __realloc = this->_M_requires_reallocation(this->size() + __n);
693         difference_type __offset = __position.base() - _Base::cbegin();
694         _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
695         if (__realloc)
696           this->_M_invalidate_all();
697         else
698           this->_M_invalidate_after_nth(__offset);
699         this->_M_update_guaranteed_capacity();
700         return { __res, this };
701       }
702 #else
703       void
704       insert(iterator __position, size_type __n, const _Tp& __x)
705       {
706         __glibcxx_check_insert(__position);
707         bool __realloc = this->_M_requires_reallocation(this->size() + __n);
708         difference_type __offset = __position.base() - _Base::begin();
709         _Base::insert(__position.base(), __n, __x);
710         if (__realloc)
711           this->_M_invalidate_all();
712         else
713           this->_M_invalidate_after_nth(__offset);
714         this->_M_update_guaranteed_capacity();
715       }
716 #endif
718 #if __cplusplus >= 201103L
719       template<class _InputIterator,
720                typename = std::_RequireInputIter<_InputIterator>>
721         _GLIBCXX20_CONSTEXPR
722         iterator
723         insert(const_iterator __position,
724                _InputIterator __first, _InputIterator __last)
725         {
726           if (std::__is_constant_evaluated())
727             return iterator(_Base::insert(__position.base(),
728                                           __gnu_debug::__unsafe(__first),
729                                           __gnu_debug::__unsafe(__last)), this);
731           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
732           __glibcxx_check_insert_range(__position, __first, __last, __dist);
734           /* Hard to guess if invalidation will occur, because __last
735              - __first can't be calculated in all cases, so we just
736              punt here by checking if it did occur. */
737           _Base_iterator __old_begin = _M_base().begin();
738           difference_type __offset = __position.base() - _Base::cbegin();
739           _Base_iterator __res;
740           if (__dist.second >= __gnu_debug::__dp_sign)
741             __res = _Base::insert(__position.base(),
742                                   __gnu_debug::__unsafe(__first),
743                                   __gnu_debug::__unsafe(__last));
744           else
745             __res = _Base::insert(__position.base(), __first, __last);
747           if (_M_base().begin() != __old_begin)
748             this->_M_invalidate_all();
749           else
750             this->_M_invalidate_after_nth(__offset);
751           this->_M_update_guaranteed_capacity();
752           return { __res, this };
753         }
754 #else
755       template<class _InputIterator>
756         void
757         insert(iterator __position,
758                _InputIterator __first, _InputIterator __last)
759         {
760           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
761           __glibcxx_check_insert_range(__position, __first, __last, __dist);
763           /* Hard to guess if invalidation will occur, because __last
764              - __first can't be calculated in all cases, so we just
765              punt here by checking if it did occur. */
766           _Base_iterator __old_begin = _M_base().begin();
767           difference_type __offset = __position.base() - _Base::begin();
768           if (__dist.second >= __gnu_debug::__dp_sign)
769             _Base::insert(__position.base(), __gnu_debug::__unsafe(__first),
770                                              __gnu_debug::__unsafe(__last));
771           else
772             _Base::insert(__position.base(), __first, __last);
774           if (_M_base().begin() != __old_begin)
775             this->_M_invalidate_all();
776           else
777             this->_M_invalidate_after_nth(__offset);
778           this->_M_update_guaranteed_capacity();
779         }
780 #endif
782       _GLIBCXX20_CONSTEXPR
783       iterator
784 #if __cplusplus >= 201103L
785       erase(const_iterator __position)
786 #else
787       erase(iterator __position)
788 #endif
789       {
790         if (std::__is_constant_evaluated())
791           return iterator(_Base::erase(__position.base()), this);
793         __glibcxx_check_erase(__position);
794         difference_type __offset = __position.base() - _Base::begin();
795         _Base_iterator __res = _Base::erase(__position.base());
796         this->_M_invalidate_after_nth(__offset);
797         return iterator(__res, this);
798       }
800       _GLIBCXX20_CONSTEXPR
801       iterator
802 #if __cplusplus >= 201103L
803       erase(const_iterator __first, const_iterator __last)
804 #else
805       erase(iterator __first, iterator __last)
806 #endif
807       {
808         if (std::__is_constant_evaluated())
809           return iterator(_Base::erase(__first.base(), __last.base()), this);
811         // _GLIBCXX_RESOLVE_LIB_DEFECTS
812         // 151. can't currently clear() empty container
813         __glibcxx_check_erase_range(__first, __last);
815         if (__first.base() != __last.base())
816           {
817             difference_type __offset = __first.base() - _Base::begin();
818             _Base_iterator __res = _Base::erase(__first.base(),
819                                                 __last.base());
820             this->_M_invalidate_after_nth(__offset);
821             return iterator(__res, this);
822           }
823         else
824 #if __cplusplus >= 201103L
825           return { _Base::begin() + (__first.base() - _Base::cbegin()), this };
826 #else
827           return __first;
828 #endif
829       }
831       _GLIBCXX20_CONSTEXPR
832       void
833       swap(vector& __x)
834       _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
835       {
836         if (!std::__is_constant_evaluated())
837           _Safe::_M_swap(__x);
838         _Base::swap(__x);
839         std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
840       }
842       _GLIBCXX20_CONSTEXPR
843       void
844       clear() _GLIBCXX_NOEXCEPT
845       {
846         _Base::clear();
847         if (!std::__is_constant_evaluated())
848           this->_M_invalidate_all();
849       }
851       _GLIBCXX20_CONSTEXPR
852       _Base&
853       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
855       _GLIBCXX20_CONSTEXPR
856       const _Base&
857       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
859     private:
860       void
861       _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
862       {
863         typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
864         this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
865       }
866     };
868   template<typename _Tp, typename _Alloc>
869     _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
870     inline bool
871     operator==(const vector<_Tp, _Alloc>& __lhs,
872                const vector<_Tp, _Alloc>& __rhs)
873     { return __lhs._M_base() == __rhs._M_base(); }
875 #if __cpp_lib_three_way_comparison
876   template<typename _Tp, typename _Alloc>
877     [[nodiscard]]
878     constexpr __detail::__synth3way_t<_Tp>
879     operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
880     { return __x._M_base() <=> __y._M_base(); }
881 #else
882   template<typename _Tp, typename _Alloc>
883     _GLIBCXX_NODISCARD
884     inline bool
885     operator!=(const vector<_Tp, _Alloc>& __lhs,
886                const vector<_Tp, _Alloc>& __rhs)
887     { return __lhs._M_base() != __rhs._M_base(); }
889   template<typename _Tp, typename _Alloc>
890     _GLIBCXX_NODISCARD
891     inline bool
892     operator<(const vector<_Tp, _Alloc>& __lhs,
893               const vector<_Tp, _Alloc>& __rhs)
894     { return __lhs._M_base() < __rhs._M_base(); }
896   template<typename _Tp, typename _Alloc>
897     _GLIBCXX_NODISCARD
898     inline bool
899     operator<=(const vector<_Tp, _Alloc>& __lhs,
900                const vector<_Tp, _Alloc>& __rhs)
901     { return __lhs._M_base() <= __rhs._M_base(); }
903   template<typename _Tp, typename _Alloc>
904     _GLIBCXX_NODISCARD
905     inline bool
906     operator>=(const vector<_Tp, _Alloc>& __lhs,
907                const vector<_Tp, _Alloc>& __rhs)
908     { return __lhs._M_base() >= __rhs._M_base(); }
910   template<typename _Tp, typename _Alloc>
911     _GLIBCXX_NODISCARD
912     inline bool
913     operator>(const vector<_Tp, _Alloc>& __lhs,
914               const vector<_Tp, _Alloc>& __rhs)
915     { return __lhs._M_base() > __rhs._M_base(); }
916 #endif // three-way comparison
918   template<typename _Tp, typename _Alloc>
919     _GLIBCXX20_CONSTEXPR
920     inline void
921     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
922     _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
923     { __lhs.swap(__rhs); }
925 #if __cpp_deduction_guides >= 201606
926   template<typename _InputIterator, typename _ValT
927              = typename iterator_traits<_InputIterator>::value_type,
928            typename _Allocator = allocator<_ValT>,
929            typename = _RequireInputIter<_InputIterator>,
930            typename = _RequireAllocator<_Allocator>>
931     vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
932       -> vector<_ValT, _Allocator>;
934   template<typename _Tp, typename _Allocator = allocator<_Tp>,
935            typename = _RequireAllocator<_Allocator>>
936     vector(size_t, _Tp, _Allocator = _Allocator())
937       -> vector<_Tp, _Allocator>;
938 #endif
940 } // namespace __debug
942 _GLIBCXX_BEGIN_NAMESPACE_VERSION
944 #if __cplusplus >= 201103L
945   // DR 1182.
946   /// std::hash specialization for vector<bool>.
947   template<typename _Alloc>
948     struct hash<__debug::vector<bool, _Alloc>>
949     : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
950     {
951       size_t
952       operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
953       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
954     };
955 #endif
957 #if __cplusplus >= 201703L
958   namespace __detail::__variant
959   {
960     template<typename> struct _Never_valueless_alt; // see <variant>
962     // Provide the strong exception-safety guarantee when emplacing a
963     // vector into a variant, but only if move assignment cannot throw.
964     template<typename _Tp, typename _Alloc>
965       struct _Never_valueless_alt<__debug::vector<_Tp, _Alloc>>
966       : std::is_nothrow_move_assignable<__debug::vector<_Tp, _Alloc>>
967       { };
968   }  // namespace __detail::__variant
969 #endif // C++17
971 _GLIBCXX_END_NAMESPACE_VERSION
972 } // namespace std
974 namespace __gnu_debug
976   template<typename _Tp, typename _Alloc>
977     struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
978     : std::__true_type
979     { };
981   template<typename _Alloc>
982     struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> >
983     : std::__false_type
984     { };
987 #endif