libstdc++
debug/vector
Go to the documentation of this file.
1// Debugging vector implementation -*- C++ -*-
2
3// Copyright (C) 2003-2019 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 template<typename _Tp, typename _Alloc>
735 inline bool
736 operator!=(const vector<_Tp, _Alloc>& __lhs,
737 const vector<_Tp, _Alloc>& __rhs)
738 { return __lhs._M_base() != __rhs._M_base(); }
739
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 void
766 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
767 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
768 { __lhs.swap(__rhs); }
769
770#if __cpp_deduction_guides >= 201606
771 template<typename _InputIterator, typename _ValT
772 = typename iterator_traits<_InputIterator>::value_type,
773 typename _Allocator = allocator<_ValT>,
774 typename = _RequireInputIter<_InputIterator>,
775 typename = _RequireAllocator<_Allocator>>
776 vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
777 -> vector<_ValT, _Allocator>;
778#endif
779
780} // namespace __debug
781
782_GLIBCXX_BEGIN_NAMESPACE_VERSION
783
784#if __cplusplus >= 201103L
785 // DR 1182.
786 /// std::hash specialization for vector<bool>.
787 template<typename _Alloc>
788 struct hash<__debug::vector<bool, _Alloc>>
789 : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
790 {
791 size_t
792 operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
793 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
794 };
795#endif
796
797 template<typename _Iterator, typename _Container, typename _Sequence>
798 _Iterator
799 __niter_base(const __gnu_debug::_Safe_iterator<
800 __gnu_cxx::__normal_iterator<_Iterator, _Container>,
801 _Sequence, std::random_access_iterator_tag>& __it)
802 { return std::__niter_base(__it.base()); }
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