1// Debugging vector implementation -*- C++ -*-
2
3// Copyright (C) 2003-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file debug/vector
26 *  This file is a GNU debug extension to the Standard C++ Library.
27 */
28
29#ifndef _GLIBCXX_DEBUG_VECTOR
30#define _GLIBCXX_DEBUG_VECTOR 1
31
32#pragma GCC system_header
33
34#include <bits/c++config.h>
35namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
36  template<typename _Tp, typename _Allocator> class vector;
37} } // namespace std::__debug
38
39#include <vector>
40#include <utility>
41#include <debug/safe_sequence.h>
42#include <debug/safe_container.h>
43#include <debug/safe_iterator.h>
44
45namespace __gnu_debug
46{
47  /** @brief Base class for Debug Mode vector.
48   *
49   * Adds information about the guaranteed capacity, which is useful for
50   * detecting code which relies on non-portable implementation details of
51   * the libstdc++ reallocation policy.
52   */
53  template<typename _SafeSequence,
54	   typename _BaseSequence>
55    class _Safe_vector
56    {
57      typedef typename _BaseSequence::size_type size_type;
58
59      const _SafeSequence&
60      _M_seq() const { return *static_cast<const _SafeSequence*>(this); }
61
62    protected:
63      _Safe_vector() _GLIBCXX_NOEXCEPT
64	: _M_guaranteed_capacity(0)
65      { _M_update_guaranteed_capacity(); }
66
67      _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
68	: _M_guaranteed_capacity(0)
69      { _M_update_guaranteed_capacity(); }
70
71      _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
72	: _M_guaranteed_capacity(__n)
73      { }
74
75#if __cplusplus >= 201103L
76      _Safe_vector(_Safe_vector&& __x) noexcept
77	: _Safe_vector()
78      { __x._M_guaranteed_capacity = 0; }
79
80      _Safe_vector&
81      operator=(const _Safe_vector&) noexcept
82      {
83	_M_update_guaranteed_capacity();
84	return *this;
85      }
86
87      _Safe_vector&
88      operator=(_Safe_vector&& __x) noexcept
89      {
90	_M_update_guaranteed_capacity();
91	__x._M_guaranteed_capacity = 0;
92	return *this;
93      }
94#endif
95
96      size_type _M_guaranteed_capacity;
97
98      bool
99      _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
100      { return __elements > _M_seq().capacity(); }
101
102      void
103      _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
104      {
105	if (_M_seq().size() > _M_guaranteed_capacity)
106	  _M_guaranteed_capacity = _M_seq().size();
107      }
108    };
109}
110
111namespace std _GLIBCXX_VISIBILITY(default)
112{
113namespace __debug
114{
115  /// Class std::vector with safety/checking/debug instrumentation.
116  template<typename _Tp,
117	   typename _Allocator = std::allocator<_Tp> >
118    class vector
119    : public __gnu_debug::_Safe_container<
120	vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
121      public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
122      public __gnu_debug::_Safe_vector<
123	vector<_Tp, _Allocator>,
124	_GLIBCXX_STD_C::vector<_Tp, _Allocator> >
125    {
126      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>		_Base;
127      typedef __gnu_debug::_Safe_container<
128	vector, _Allocator, __gnu_debug::_Safe_sequence>	_Safe;
129      typedef __gnu_debug::_Safe_vector<vector, _Base>		_Safe_vector;
130
131      typedef typename _Base::iterator		_Base_iterator;
132      typedef typename _Base::const_iterator	_Base_const_iterator;
133      typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
134
135      template<typename _ItT, typename _SeqT, typename _CatT>
136	friend class ::__gnu_debug::_Safe_iterator;
137
138    public:
139      typedef typename _Base::reference			reference;
140      typedef typename _Base::const_reference		const_reference;
141
142      typedef __gnu_debug::_Safe_iterator<
143	_Base_iterator, vector>				iterator;
144      typedef __gnu_debug::_Safe_iterator<
145	_Base_const_iterator, vector>			const_iterator;
146
147      typedef typename _Base::size_type			size_type;
148      typedef typename _Base::difference_type		difference_type;
149
150      typedef _Tp					value_type;
151      typedef _Allocator				allocator_type;
152      typedef typename _Base::pointer			pointer;
153      typedef typename _Base::const_pointer		const_pointer;
154      typedef std::reverse_iterator<iterator>		reverse_iterator;
155      typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
156
157      // 23.2.4.1 construct/copy/destroy:
158
159#if __cplusplus < 201103L
160      vector() _GLIBCXX_NOEXCEPT
161      : _Base() { }
162#else
163      vector() = default;
164#endif
165
166      explicit
167      vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
168      : _Base(__a) { }
169
170#if __cplusplus >= 201103L
171      explicit
172      vector(size_type __n, const _Allocator& __a = _Allocator())
173      : _Base(__n, __a), _Safe_vector(__n) { }
174
175      vector(size_type __n, const _Tp& __value,
176	     const _Allocator& __a = _Allocator())
177      : _Base(__n, __value, __a) { }
178#else
179      explicit
180      vector(size_type __n, const _Tp& __value = _Tp(),
181	     const _Allocator& __a = _Allocator())
182      : _Base(__n, __value, __a) { }
183#endif
184
185#if __cplusplus >= 201103L
186      template<class _InputIterator,
187	       typename = std::_RequireInputIter<_InputIterator>>
188#else
189      template<class _InputIterator>
190#endif
191	vector(_InputIterator __first, _InputIterator __last,
192	       const _Allocator& __a = _Allocator())
193	: _Base(__gnu_debug::__base(
194		  __glibcxx_check_valid_constructor_range(__first, __last)),
195		__gnu_debug::__base(__last), __a) { }
196
197#if __cplusplus < 201103L
198      vector(const vector& __x)
199      : _Base(__x) { }
200
201      ~vector() _GLIBCXX_NOEXCEPT { }
202#else
203      vector(const vector&) = default;
204      vector(vector&&) = default;
205
206      vector(const vector& __x, const allocator_type& __a)
207      : _Base(__x, __a) { }
208
209      vector(vector&& __x, const allocator_type& __a)
210	noexcept( noexcept(
211	  _Base(std::declval<_Base&&>()), std::declval<const allocator_type&>()) )
212      : _Safe(std::move(__x._M_safe()), __a),
213	_Base(std::move(__x._M_base()), __a),
214	_Safe_vector(std::move(__x)) { }
215
216      vector(initializer_list<value_type> __l,
217	     const allocator_type& __a = allocator_type())
218      : _Base(__l, __a) { }
219
220      ~vector() = default;
221#endif
222
223      /// Construction from a normal-mode vector
224      vector(const _Base& __x)
225      : _Base(__x) { }
226
227#if __cplusplus < 201103L
228      vector&
229      operator=(const vector& __x)
230      {
231	this->_M_safe() = __x;
232	_M_base() = __x;
233	this->_M_update_guaranteed_capacity();
234	return *this;
235      }
236#else
237      vector&
238      operator=(const vector&) = default;
239
240      vector&
241      operator=(vector&&) = default;
242
243      vector&
244      operator=(initializer_list<value_type> __l)
245      {
246	_M_base() = __l;
247	this->_M_invalidate_all();
248	this->_M_update_guaranteed_capacity();
249	return *this;
250      }
251#endif
252
253#if __cplusplus >= 201103L
254      template<typename _InputIterator,
255	       typename = std::_RequireInputIter<_InputIterator>>
256#else
257      template<typename _InputIterator>
258#endif
259	void
260	assign(_InputIterator __first, _InputIterator __last)
261	{
262	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
263	  __glibcxx_check_valid_range2(__first, __last, __dist);
264
265	  if (__dist.second >= __gnu_debug::__dp_sign)
266	    _Base::assign(__gnu_debug::__unsafe(__first),
267			  __gnu_debug::__unsafe(__last));
268	  else
269	    _Base::assign(__first, __last);
270
271	  this->_M_invalidate_all();
272	  this->_M_update_guaranteed_capacity();
273	}
274
275      void
276      assign(size_type __n, const _Tp& __u)
277      {
278	_Base::assign(__n, __u);
279	this->_M_invalidate_all();
280	this->_M_update_guaranteed_capacity();
281      }
282
283#if __cplusplus >= 201103L
284      void
285      assign(initializer_list<value_type> __l)
286      {
287	_Base::assign(__l);
288	this->_M_invalidate_all();
289	this->_M_update_guaranteed_capacity();
290      }
291#endif
292
293      using _Base::get_allocator;
294
295      // iterators:
296      iterator
297      begin() _GLIBCXX_NOEXCEPT
298      { return iterator(_Base::begin(), this); }
299
300      const_iterator
301      begin() const _GLIBCXX_NOEXCEPT
302      { return const_iterator(_Base::begin(), this); }
303
304      iterator
305      end() _GLIBCXX_NOEXCEPT
306      { return iterator(_Base::end(), this); }
307
308      const_iterator
309      end() const _GLIBCXX_NOEXCEPT
310      { return const_iterator(_Base::end(), this); }
311
312      reverse_iterator
313      rbegin() _GLIBCXX_NOEXCEPT
314      { return reverse_iterator(end()); }
315
316      const_reverse_iterator
317      rbegin() const _GLIBCXX_NOEXCEPT
318      { return const_reverse_iterator(end()); }
319
320      reverse_iterator
321      rend() _GLIBCXX_NOEXCEPT
322      { return reverse_iterator(begin()); }
323
324      const_reverse_iterator
325      rend() const _GLIBCXX_NOEXCEPT
326      { return const_reverse_iterator(begin()); }
327
328#if __cplusplus >= 201103L
329      const_iterator
330      cbegin() const noexcept
331      { return const_iterator(_Base::begin(), this); }
332
333      const_iterator
334      cend() const noexcept
335      { return const_iterator(_Base::end(), this); }
336
337      const_reverse_iterator
338      crbegin() const noexcept
339      { return const_reverse_iterator(end()); }
340
341      const_reverse_iterator
342      crend() const noexcept
343      { return const_reverse_iterator(begin()); }
344#endif
345
346      // 23.2.4.2 capacity:
347      using _Base::size;
348      using _Base::max_size;
349
350#if __cplusplus >= 201103L
351      void
352      resize(size_type __sz)
353      {
354	bool __realloc = this->_M_requires_reallocation(__sz);
355	if (__sz < this->size())
356	  this->_M_invalidate_after_nth(__sz);
357	_Base::resize(__sz);
358	if (__realloc)
359	  this->_M_invalidate_all();
360	this->_M_update_guaranteed_capacity();
361      }
362
363      void
364      resize(size_type __sz, const _Tp& __c)
365      {
366	bool __realloc = this->_M_requires_reallocation(__sz);
367	if (__sz < this->size())
368	  this->_M_invalidate_after_nth(__sz);
369	_Base::resize(__sz, __c);
370	if (__realloc)
371	  this->_M_invalidate_all();
372	this->_M_update_guaranteed_capacity();
373      }
374#else
375      void
376      resize(size_type __sz, _Tp __c = _Tp())
377      {
378	bool __realloc = this->_M_requires_reallocation(__sz);
379	if (__sz < this->size())
380	  this->_M_invalidate_after_nth(__sz);
381	_Base::resize(__sz, __c);
382	if (__realloc)
383	  this->_M_invalidate_all();
384	this->_M_update_guaranteed_capacity();
385      }
386#endif
387
388#if __cplusplus >= 201103L
389      void
390      shrink_to_fit()
391      {
392	if (_Base::_M_shrink_to_fit())
393	  {
394	    this->_M_guaranteed_capacity = _Base::capacity();
395	    this->_M_invalidate_all();
396	  }
397      }
398#endif
399
400      size_type
401      capacity() const _GLIBCXX_NOEXCEPT
402      {
403#ifdef _GLIBCXX_DEBUG_PEDANTIC
404	return this->_M_guaranteed_capacity;
405#else
406	return _Base::capacity();
407#endif
408      }
409
410      using _Base::empty;
411
412      void
413      reserve(size_type __n)
414      {
415	bool __realloc = this->_M_requires_reallocation(__n);
416	_Base::reserve(__n);
417	if (__n > this->_M_guaranteed_capacity)
418	  this->_M_guaranteed_capacity = __n;
419	if (__realloc)
420	  this->_M_invalidate_all();
421      }
422
423      // element access:
424      reference
425      operator[](size_type __n) _GLIBCXX_NOEXCEPT
426      {
427	__glibcxx_check_subscript(__n);
428	return _M_base()[__n];
429      }
430
431      const_reference
432      operator[](size_type __n) const _GLIBCXX_NOEXCEPT
433      {
434	__glibcxx_check_subscript(__n);
435	return _M_base()[__n];
436      }
437
438      using _Base::at;
439
440      reference
441      front() _GLIBCXX_NOEXCEPT
442      {
443	__glibcxx_check_nonempty();
444	return _Base::front();
445      }
446
447      const_reference
448      front() const _GLIBCXX_NOEXCEPT
449      {
450	__glibcxx_check_nonempty();
451	return _Base::front();
452      }
453
454      reference
455      back() _GLIBCXX_NOEXCEPT
456      {
457	__glibcxx_check_nonempty();
458	return _Base::back();
459      }
460
461      const_reference
462      back() const _GLIBCXX_NOEXCEPT
463      {
464	__glibcxx_check_nonempty();
465	return _Base::back();
466      }
467
468      // _GLIBCXX_RESOLVE_LIB_DEFECTS
469      // DR 464. Suggestion for new member functions in standard containers.
470      using _Base::data;
471
472      // 23.2.4.3 modifiers:
473      void
474      push_back(const _Tp& __x)
475      {
476	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
477	_Base::push_back(__x);
478	if (__realloc)
479	  this->_M_invalidate_all();
480	this->_M_update_guaranteed_capacity();
481      }
482
483#if __cplusplus >= 201103L
484      template<typename _Up = _Tp>
485	typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
486					void>::__type
487	push_back(_Tp&& __x)
488	{ emplace_back(std::move(__x)); }
489
490      template<typename... _Args>
491#if __cplusplus > 201402L
492	reference
493#else
494	void
495#endif
496	emplace_back(_Args&&... __args)
497	{
498	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
499	  _Base::emplace_back(std::forward<_Args>(__args)...);
500	  if (__realloc)
501	    this->_M_invalidate_all();
502	  this->_M_update_guaranteed_capacity();
503#if __cplusplus > 201402L
504	  return back();
505#endif
506	}
507#endif
508
509      void
510      pop_back() _GLIBCXX_NOEXCEPT
511      {
512	__glibcxx_check_nonempty();
513	this->_M_invalidate_if(_Equal(--_Base::end()));
514	_Base::pop_back();
515      }
516
517#if __cplusplus >= 201103L
518      template<typename... _Args>
519	iterator
520	emplace(const_iterator __position, _Args&&... __args)
521	{
522	  __glibcxx_check_insert(__position);
523	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
524	  difference_type __offset = __position.base() - _Base::cbegin();
525	  _Base_iterator __res = _Base::emplace(__position.base(),
526						std::forward<_Args>(__args)...);
527	  if (__realloc)
528	    this->_M_invalidate_all();
529	  else
530	    this->_M_invalidate_after_nth(__offset);
531	  this->_M_update_guaranteed_capacity();
532	  return { __res, this };
533	}
534#endif
535
536      iterator
537#if __cplusplus >= 201103L
538      insert(const_iterator __position, const _Tp& __x)
539#else
540      insert(iterator __position, const _Tp& __x)
541#endif
542      {
543	__glibcxx_check_insert(__position);
544	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
545	difference_type __offset = __position.base() - _Base::begin();
546	_Base_iterator __res = _Base::insert(__position.base(), __x);
547	if (__realloc)
548	  this->_M_invalidate_all();
549	else
550	  this->_M_invalidate_after_nth(__offset);
551	this->_M_update_guaranteed_capacity();
552	return iterator(__res, this);
553      }
554
555#if __cplusplus >= 201103L
556      template<typename _Up = _Tp>
557	typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
558					iterator>::__type
559	insert(const_iterator __position, _Tp&& __x)
560	{ return emplace(__position, std::move(__x)); }
561
562      iterator
563      insert(const_iterator __position, initializer_list<value_type> __l)
564      { return this->insert(__position, __l.begin(), __l.end()); }
565#endif
566
567#if __cplusplus >= 201103L
568      iterator
569      insert(const_iterator __position, size_type __n, const _Tp& __x)
570      {
571	__glibcxx_check_insert(__position);
572	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
573	difference_type __offset = __position.base() - _Base::cbegin();
574	_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
575	if (__realloc)
576	  this->_M_invalidate_all();
577	else
578	  this->_M_invalidate_after_nth(__offset);
579	this->_M_update_guaranteed_capacity();
580	return { __res, this };
581      }
582#else
583      void
584      insert(iterator __position, size_type __n, const _Tp& __x)
585      {
586	__glibcxx_check_insert(__position);
587	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
588	difference_type __offset = __position.base() - _Base::begin();
589	_Base::insert(__position.base(), __n, __x);
590	if (__realloc)
591	  this->_M_invalidate_all();
592	else
593	  this->_M_invalidate_after_nth(__offset);
594	this->_M_update_guaranteed_capacity();
595      }
596#endif
597
598#if __cplusplus >= 201103L
599      template<class _InputIterator,
600	       typename = std::_RequireInputIter<_InputIterator>>
601	iterator
602	insert(const_iterator __position,
603	       _InputIterator __first, _InputIterator __last)
604	{
605	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
606	  __glibcxx_check_insert_range(__position, __first, __last, __dist);
607
608	  /* Hard to guess if invalidation will occur, because __last
609	     - __first can't be calculated in all cases, so we just
610	     punt here by checking if it did occur. */
611	  _Base_iterator __old_begin = _M_base().begin();
612	  difference_type __offset = __position.base() - _Base::cbegin();
613	  _Base_iterator __res;
614	  if (__dist.second >= __gnu_debug::__dp_sign)
615	    __res = _Base::insert(__position.base(),
616				  __gnu_debug::__unsafe(__first),
617				  __gnu_debug::__unsafe(__last));
618	  else
619	    __res = _Base::insert(__position.base(), __first, __last);
620
621	  if (_M_base().begin() != __old_begin)
622	    this->_M_invalidate_all();
623	  else
624	    this->_M_invalidate_after_nth(__offset);
625	  this->_M_update_guaranteed_capacity();
626	  return { __res, this };
627	}
628#else
629      template<class _InputIterator>
630	void
631	insert(iterator __position,
632	       _InputIterator __first, _InputIterator __last)
633	{
634	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
635	  __glibcxx_check_insert_range(__position, __first, __last, __dist);
636
637	  /* Hard to guess if invalidation will occur, because __last
638	     - __first can't be calculated in all cases, so we just
639	     punt here by checking if it did occur. */
640	  _Base_iterator __old_begin = _M_base().begin();
641	  difference_type __offset = __position.base() - _Base::begin();
642	  if (__dist.second >= __gnu_debug::__dp_sign)
643	    _Base::insert(__position.base(), __gnu_debug::__unsafe(__first),
644					     __gnu_debug::__unsafe(__last));
645	  else
646	    _Base::insert(__position.base(), __first, __last);
647
648	  if (_M_base().begin() != __old_begin)
649	    this->_M_invalidate_all();
650	  else
651	    this->_M_invalidate_after_nth(__offset);
652	  this->_M_update_guaranteed_capacity();
653	}
654#endif
655
656      iterator
657#if __cplusplus >= 201103L
658      erase(const_iterator __position)
659#else
660      erase(iterator __position)
661#endif
662      {
663	__glibcxx_check_erase(__position);
664	difference_type __offset = __position.base() - _Base::begin();
665	_Base_iterator __res = _Base::erase(__position.base());
666	this->_M_invalidate_after_nth(__offset);
667	return iterator(__res, this);
668      }
669
670      iterator
671#if __cplusplus >= 201103L
672      erase(const_iterator __first, const_iterator __last)
673#else
674      erase(iterator __first, iterator __last)
675#endif
676      {
677	// _GLIBCXX_RESOLVE_LIB_DEFECTS
678	// 151. can't currently clear() empty container
679	__glibcxx_check_erase_range(__first, __last);
680
681	if (__first.base() != __last.base())
682	  {
683	    difference_type __offset = __first.base() - _Base::begin();
684	    _Base_iterator __res = _Base::erase(__first.base(),
685						__last.base());
686	    this->_M_invalidate_after_nth(__offset);
687	    return iterator(__res, this);
688	  }
689	else
690#if __cplusplus >= 201103L
691	  return { _Base::begin() + (__first.base() - _Base::cbegin()), this };
692#else
693	  return __first;
694#endif
695      }
696
697      void
698      swap(vector& __x)
699      _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
700      {
701	_Safe::_M_swap(__x);
702	_Base::swap(__x);
703	std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
704      }
705
706      void
707      clear() _GLIBCXX_NOEXCEPT
708      {
709	_Base::clear();
710	this->_M_invalidate_all();
711      }
712
713      _Base&
714      _M_base() _GLIBCXX_NOEXCEPT { return *this; }
715
716      const _Base&
717      _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
718
719    private:
720      void
721      _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
722      {
723	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
724	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
725      }
726    };
727
728  template<typename _Tp, typename _Alloc>
729    inline bool
730    operator==(const vector<_Tp, _Alloc>& __lhs,
731	       const vector<_Tp, _Alloc>& __rhs)
732    { return __lhs._M_base() == __rhs._M_base(); }
733
734#if __cpp_lib_three_way_comparison
735  template<typename _Tp, typename _Alloc>
736    constexpr __detail::__synth3way_t<_Tp>
737    operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
738    { return __x._M_base() <=> __y._M_base(); }
739#else
740  template<typename _Tp, typename _Alloc>
741    inline bool
742    operator!=(const vector<_Tp, _Alloc>& __lhs,
743	       const vector<_Tp, _Alloc>& __rhs)
744    { return __lhs._M_base() != __rhs._M_base(); }
745
746  template<typename _Tp, typename _Alloc>
747    inline bool
748    operator<(const vector<_Tp, _Alloc>& __lhs,
749	      const vector<_Tp, _Alloc>& __rhs)
750    { return __lhs._M_base() < __rhs._M_base(); }
751
752  template<typename _Tp, typename _Alloc>
753    inline bool
754    operator<=(const vector<_Tp, _Alloc>& __lhs,
755	       const vector<_Tp, _Alloc>& __rhs)
756    { return __lhs._M_base() <= __rhs._M_base(); }
757
758  template<typename _Tp, typename _Alloc>
759    inline bool
760    operator>=(const vector<_Tp, _Alloc>& __lhs,
761	       const vector<_Tp, _Alloc>& __rhs)
762    { return __lhs._M_base() >= __rhs._M_base(); }
763
764  template<typename _Tp, typename _Alloc>
765    inline bool
766    operator>(const vector<_Tp, _Alloc>& __lhs,
767	      const vector<_Tp, _Alloc>& __rhs)
768    { return __lhs._M_base() > __rhs._M_base(); }
769#endif // three-way comparison
770
771  template<typename _Tp, typename _Alloc>
772    inline void
773    swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
774    _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
775    { __lhs.swap(__rhs); }
776
777#if __cpp_deduction_guides >= 201606
778  template<typename _InputIterator, typename _ValT
779	     = typename iterator_traits<_InputIterator>::value_type,
780	   typename _Allocator = allocator<_ValT>,
781	   typename = _RequireInputIter<_InputIterator>,
782	   typename = _RequireAllocator<_Allocator>>
783    vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
784      -> vector<_ValT, _Allocator>;
785#endif
786
787} // namespace __debug
788
789_GLIBCXX_BEGIN_NAMESPACE_VERSION
790
791#if __cplusplus >= 201103L
792  // DR 1182.
793  /// std::hash specialization for vector<bool>.
794  template<typename _Alloc>
795    struct hash<__debug::vector<bool, _Alloc>>
796    : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
797    {
798      size_t
799      operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
800      { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
801    };
802#endif
803
804#if __cplusplus >= 201703L
805  namespace __detail::__variant
806  {
807    template<typename> struct _Never_valueless_alt; // see <variant>
808
809    // Provide the strong exception-safety guarantee when emplacing a
810    // vector into a variant, but only if move assignment cannot throw.
811    template<typename _Tp, typename _Alloc>
812      struct _Never_valueless_alt<__debug::vector<_Tp, _Alloc>>
813      : std::is_nothrow_move_assignable<__debug::vector<_Tp, _Alloc>>
814      { };
815  }  // namespace __detail::__variant
816#endif // C++17
817
818_GLIBCXX_END_NAMESPACE_VERSION
819} // namespace std
820
821namespace __gnu_debug
822{
823  template<typename _Tp, typename _Alloc>
824    struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
825    : std::__true_type
826    { };
827
828  template<typename _Alloc>
829    struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> >
830    : std::__false_type
831    { };
832}
833
834#endif
835