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