1// Debugging vector implementation -*- C++ -*- 2 3// Copyright (C) 2003-2015 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 __glibcxx_check_valid_range(__first, __last); 251 _Base::assign(__gnu_debug::__base(__first), 252 __gnu_debug::__base(__last)); 253 this->_M_invalidate_all(); 254 this->_M_update_guaranteed_capacity(); 255 } 256 257 void 258 assign(size_type __n, const _Tp& __u) 259 { 260 _Base::assign(__n, __u); 261 this->_M_invalidate_all(); 262 this->_M_update_guaranteed_capacity(); 263 } 264 265#if __cplusplus >= 201103L 266 void 267 assign(initializer_list<value_type> __l) 268 { 269 _Base::assign(__l); 270 this->_M_invalidate_all(); 271 this->_M_update_guaranteed_capacity(); 272 } 273#endif 274 275 using _Base::get_allocator; 276 277 // iterators: 278 iterator 279 begin() _GLIBCXX_NOEXCEPT 280 { return iterator(_Base::begin(), this); } 281 282 const_iterator 283 begin() const _GLIBCXX_NOEXCEPT 284 { return const_iterator(_Base::begin(), this); } 285 286 iterator 287 end() _GLIBCXX_NOEXCEPT 288 { return iterator(_Base::end(), this); } 289 290 const_iterator 291 end() const _GLIBCXX_NOEXCEPT 292 { return const_iterator(_Base::end(), this); } 293 294 reverse_iterator 295 rbegin() _GLIBCXX_NOEXCEPT 296 { return reverse_iterator(end()); } 297 298 const_reverse_iterator 299 rbegin() const _GLIBCXX_NOEXCEPT 300 { return const_reverse_iterator(end()); } 301 302 reverse_iterator 303 rend() _GLIBCXX_NOEXCEPT 304 { return reverse_iterator(begin()); } 305 306 const_reverse_iterator 307 rend() const _GLIBCXX_NOEXCEPT 308 { return const_reverse_iterator(begin()); } 309 310#if __cplusplus >= 201103L 311 const_iterator 312 cbegin() const noexcept 313 { return const_iterator(_Base::begin(), this); } 314 315 const_iterator 316 cend() const noexcept 317 { return const_iterator(_Base::end(), this); } 318 319 const_reverse_iterator 320 crbegin() const noexcept 321 { return const_reverse_iterator(end()); } 322 323 const_reverse_iterator 324 crend() const noexcept 325 { return const_reverse_iterator(begin()); } 326#endif 327 328 // 23.2.4.2 capacity: 329 using _Base::size; 330 using _Base::max_size; 331 332#if __cplusplus >= 201103L 333 void 334 resize(size_type __sz) 335 { 336 bool __realloc = this->_M_requires_reallocation(__sz); 337 if (__sz < this->size()) 338 this->_M_invalidate_after_nth(__sz); 339 _Base::resize(__sz); 340 if (__realloc) 341 this->_M_invalidate_all(); 342 this->_M_update_guaranteed_capacity(); 343 } 344 345 void 346 resize(size_type __sz, const _Tp& __c) 347 { 348 bool __realloc = this->_M_requires_reallocation(__sz); 349 if (__sz < this->size()) 350 this->_M_invalidate_after_nth(__sz); 351 _Base::resize(__sz, __c); 352 if (__realloc) 353 this->_M_invalidate_all(); 354 this->_M_update_guaranteed_capacity(); 355 } 356#else 357 void 358 resize(size_type __sz, _Tp __c = _Tp()) 359 { 360 bool __realloc = this->_M_requires_reallocation(__sz); 361 if (__sz < this->size()) 362 this->_M_invalidate_after_nth(__sz); 363 _Base::resize(__sz, __c); 364 if (__realloc) 365 this->_M_invalidate_all(); 366 this->_M_update_guaranteed_capacity(); 367 } 368#endif 369 370#if __cplusplus >= 201103L 371 void 372 shrink_to_fit() 373 { 374 if (_Base::_M_shrink_to_fit()) 375 { 376 this->_M_guaranteed_capacity = _Base::capacity(); 377 this->_M_invalidate_all(); 378 } 379 } 380#endif 381 382 size_type 383 capacity() const _GLIBCXX_NOEXCEPT 384 { 385#ifdef _GLIBCXX_DEBUG_PEDANTIC 386 return this->_M_guaranteed_capacity; 387#else 388 return _Base::capacity(); 389#endif 390 } 391 392 using _Base::empty; 393 394 void 395 reserve(size_type __n) 396 { 397 bool __realloc = this->_M_requires_reallocation(__n); 398 _Base::reserve(__n); 399 if (__n > this->_M_guaranteed_capacity) 400 this->_M_guaranteed_capacity = __n; 401 if (__realloc) 402 this->_M_invalidate_all(); 403 } 404 405 // element access: 406 reference 407 operator[](size_type __n) _GLIBCXX_NOEXCEPT 408 { 409 __glibcxx_check_subscript(__n); 410 return _M_base()[__n]; 411 } 412 413 const_reference 414 operator[](size_type __n) const _GLIBCXX_NOEXCEPT 415 { 416 __glibcxx_check_subscript(__n); 417 return _M_base()[__n]; 418 } 419 420 using _Base::at; 421 422 reference 423 front() _GLIBCXX_NOEXCEPT 424 { 425 __glibcxx_check_nonempty(); 426 return _Base::front(); 427 } 428 429 const_reference 430 front() const _GLIBCXX_NOEXCEPT 431 { 432 __glibcxx_check_nonempty(); 433 return _Base::front(); 434 } 435 436 reference 437 back() _GLIBCXX_NOEXCEPT 438 { 439 __glibcxx_check_nonempty(); 440 return _Base::back(); 441 } 442 443 const_reference 444 back() const _GLIBCXX_NOEXCEPT 445 { 446 __glibcxx_check_nonempty(); 447 return _Base::back(); 448 } 449 450 // _GLIBCXX_RESOLVE_LIB_DEFECTS 451 // DR 464. Suggestion for new member functions in standard containers. 452 using _Base::data; 453 454 // 23.2.4.3 modifiers: 455 void 456 push_back(const _Tp& __x) 457 { 458 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 459 _Base::push_back(__x); 460 if (__realloc) 461 this->_M_invalidate_all(); 462 this->_M_update_guaranteed_capacity(); 463 } 464 465#if __cplusplus >= 201103L 466 template<typename _Up = _Tp> 467 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 468 void>::__type 469 push_back(_Tp&& __x) 470 { emplace_back(std::move(__x)); } 471 472 template<typename... _Args> 473 void 474 emplace_back(_Args&&... __args) 475 { 476 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 477 _Base::emplace_back(std::forward<_Args>(__args)...); 478 if (__realloc) 479 this->_M_invalidate_all(); 480 this->_M_update_guaranteed_capacity(); 481 } 482#endif 483 484 void 485 pop_back() _GLIBCXX_NOEXCEPT 486 { 487 __glibcxx_check_nonempty(); 488 this->_M_invalidate_if(_Equal(--_Base::end())); 489 _Base::pop_back(); 490 } 491 492#if __cplusplus >= 201103L 493 template<typename... _Args> 494 iterator 495 emplace(const_iterator __position, _Args&&... __args) 496 { 497 __glibcxx_check_insert(__position); 498 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 499 difference_type __offset = __position.base() - _Base::begin(); 500 _Base_iterator __res = _Base::emplace(__position.base(), 501 std::forward<_Args>(__args)...); 502 if (__realloc) 503 this->_M_invalidate_all(); 504 else 505 this->_M_invalidate_after_nth(__offset); 506 this->_M_update_guaranteed_capacity(); 507 return iterator(__res, this); 508 } 509#endif 510 511 iterator 512#if __cplusplus >= 201103L 513 insert(const_iterator __position, const _Tp& __x) 514#else 515 insert(iterator __position, const _Tp& __x) 516#endif 517 { 518 __glibcxx_check_insert(__position); 519 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 520 difference_type __offset = __position.base() - _Base::begin(); 521 _Base_iterator __res = _Base::insert(__position.base(), __x); 522 if (__realloc) 523 this->_M_invalidate_all(); 524 else 525 this->_M_invalidate_after_nth(__offset); 526 this->_M_update_guaranteed_capacity(); 527 return iterator(__res, this); 528 } 529 530#if __cplusplus >= 201103L 531 template<typename _Up = _Tp> 532 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 533 iterator>::__type 534 insert(const_iterator __position, _Tp&& __x) 535 { return emplace(__position, std::move(__x)); } 536 537 iterator 538 insert(const_iterator __position, initializer_list<value_type> __l) 539 { return this->insert(__position, __l.begin(), __l.end()); } 540#endif 541 542#if __cplusplus >= 201103L 543 iterator 544 insert(const_iterator __position, size_type __n, const _Tp& __x) 545 { 546 __glibcxx_check_insert(__position); 547 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 548 difference_type __offset = __position.base() - _Base::cbegin(); 549 _Base_iterator __res = _Base::insert(__position.base(), __n, __x); 550 if (__realloc) 551 this->_M_invalidate_all(); 552 else 553 this->_M_invalidate_after_nth(__offset); 554 this->_M_update_guaranteed_capacity(); 555 return iterator(__res, this); 556 } 557#else 558 void 559 insert(iterator __position, size_type __n, const _Tp& __x) 560 { 561 __glibcxx_check_insert(__position); 562 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 563 difference_type __offset = __position.base() - _Base::begin(); 564 _Base::insert(__position.base(), __n, __x); 565 if (__realloc) 566 this->_M_invalidate_all(); 567 else 568 this->_M_invalidate_after_nth(__offset); 569 this->_M_update_guaranteed_capacity(); 570 } 571#endif 572 573#if __cplusplus >= 201103L 574 template<class _InputIterator, 575 typename = std::_RequireInputIter<_InputIterator>> 576 iterator 577 insert(const_iterator __position, 578 _InputIterator __first, _InputIterator __last) 579 { 580 __glibcxx_check_insert_range(__position, __first, __last); 581 582 /* Hard to guess if invalidation will occur, because __last 583 - __first can't be calculated in all cases, so we just 584 punt here by checking if it did occur. */ 585 _Base_iterator __old_begin = _M_base().begin(); 586 difference_type __offset = __position.base() - _Base::cbegin(); 587 _Base_iterator __res = _Base::insert(__position.base(), 588 __gnu_debug::__base(__first), 589 __gnu_debug::__base(__last)); 590 591 if (_M_base().begin() != __old_begin) 592 this->_M_invalidate_all(); 593 else 594 this->_M_invalidate_after_nth(__offset); 595 this->_M_update_guaranteed_capacity(); 596 return iterator(__res, this); 597 } 598#else 599 template<class _InputIterator> 600 void 601 insert(iterator __position, 602 _InputIterator __first, _InputIterator __last) 603 { 604 __glibcxx_check_insert_range(__position, __first, __last); 605 606 /* Hard to guess if invalidation will occur, because __last 607 - __first can't be calculated in all cases, so we just 608 punt here by checking if it did occur. */ 609 _Base_iterator __old_begin = _M_base().begin(); 610 difference_type __offset = __position.base() - _Base::begin(); 611 _Base::insert(__position.base(), __gnu_debug::__base(__first), 612 __gnu_debug::__base(__last)); 613 614 if (_M_base().begin() != __old_begin) 615 this->_M_invalidate_all(); 616 else 617 this->_M_invalidate_after_nth(__offset); 618 this->_M_update_guaranteed_capacity(); 619 } 620#endif 621 622 iterator 623#if __cplusplus >= 201103L 624 erase(const_iterator __position) 625#else 626 erase(iterator __position) 627#endif 628 { 629 __glibcxx_check_erase(__position); 630 difference_type __offset = __position.base() - _Base::begin(); 631 _Base_iterator __res = _Base::erase(__position.base()); 632 this->_M_invalidate_after_nth(__offset); 633 return iterator(__res, this); 634 } 635 636 iterator 637#if __cplusplus >= 201103L 638 erase(const_iterator __first, const_iterator __last) 639#else 640 erase(iterator __first, iterator __last) 641#endif 642 { 643 // _GLIBCXX_RESOLVE_LIB_DEFECTS 644 // 151. can't currently clear() empty container 645 __glibcxx_check_erase_range(__first, __last); 646 647 if (__first.base() != __last.base()) 648 { 649 difference_type __offset = __first.base() - _Base::begin(); 650 _Base_iterator __res = _Base::erase(__first.base(), 651 __last.base()); 652 this->_M_invalidate_after_nth(__offset); 653 return iterator(__res, this); 654 } 655 else 656#if __cplusplus >= 201103L 657 return begin() + (__first.base() - cbegin().base()); 658#else 659 return __first; 660#endif 661 } 662 663 void 664 swap(vector& __x) 665#if __cplusplus >= 201103L 666 noexcept( noexcept(declval<_Base>().swap(__x)) ) 667#endif 668 { 669 _Safe::_M_swap(__x); 670 _Base::swap(__x); 671 std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity); 672 } 673 674 void 675 clear() _GLIBCXX_NOEXCEPT 676 { 677 _Base::clear(); 678 this->_M_invalidate_all(); 679 } 680 681 _Base& 682 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 683 684 const _Base& 685 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 686 687 private: 688 void 689 _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT 690 { 691 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 692 this->_M_invalidate_if(_After_nth(__n, _Base::begin())); 693 } 694 }; 695 696 template<typename _Tp, typename _Alloc> 697 inline bool 698 operator==(const vector<_Tp, _Alloc>& __lhs, 699 const vector<_Tp, _Alloc>& __rhs) 700 { return __lhs._M_base() == __rhs._M_base(); } 701 702 template<typename _Tp, typename _Alloc> 703 inline bool 704 operator!=(const vector<_Tp, _Alloc>& __lhs, 705 const vector<_Tp, _Alloc>& __rhs) 706 { return __lhs._M_base() != __rhs._M_base(); } 707 708 template<typename _Tp, typename _Alloc> 709 inline bool 710 operator<(const vector<_Tp, _Alloc>& __lhs, 711 const vector<_Tp, _Alloc>& __rhs) 712 { return __lhs._M_base() < __rhs._M_base(); } 713 714 template<typename _Tp, typename _Alloc> 715 inline bool 716 operator<=(const vector<_Tp, _Alloc>& __lhs, 717 const vector<_Tp, _Alloc>& __rhs) 718 { return __lhs._M_base() <= __rhs._M_base(); } 719 720 template<typename _Tp, typename _Alloc> 721 inline bool 722 operator>=(const vector<_Tp, _Alloc>& __lhs, 723 const vector<_Tp, _Alloc>& __rhs) 724 { return __lhs._M_base() >= __rhs._M_base(); } 725 726 template<typename _Tp, typename _Alloc> 727 inline bool 728 operator>(const vector<_Tp, _Alloc>& __lhs, 729 const vector<_Tp, _Alloc>& __rhs) 730 { return __lhs._M_base() > __rhs._M_base(); } 731 732 template<typename _Tp, typename _Alloc> 733 inline void 734 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 735 { __lhs.swap(__rhs); } 736 737} // namespace __debug 738 739#if __cplusplus >= 201103L 740 // DR 1182. 741 /// std::hash specialization for vector<bool>. 742 template<typename _Alloc> 743 struct hash<__debug::vector<bool, _Alloc>> 744 : public __hash_base<size_t, __debug::vector<bool, _Alloc>> 745 { 746 size_t 747 operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept 748 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 749 (__b._M_base()); } 750 }; 751#endif 752 753} // namespace std 754 755namespace __gnu_debug 756{ 757 template<typename _Tp, typename _Alloc> 758 struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> > 759 : std::__true_type 760 { }; 761 762 template<typename _Alloc> 763 struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> > 764 : std::__false_type 765 { }; 766} 767 768#endif 769