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 782