libstdc++
|
00001 // Debugging vector implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003-2014 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file debug/vector 00026 * This file is a GNU debug extension to the Standard C++ Library. 00027 */ 00028 00029 #ifndef _GLIBCXX_DEBUG_VECTOR 00030 #define _GLIBCXX_DEBUG_VECTOR 1 00031 00032 #include <vector> 00033 #include <utility> 00034 #include <debug/safe_sequence.h> 00035 #include <debug/safe_iterator.h> 00036 00037 namespace std _GLIBCXX_VISIBILITY(default) 00038 { 00039 namespace __debug 00040 { 00041 /// Class std::vector with safety/checking/debug instrumentation. 00042 template<typename _Tp, 00043 typename _Allocator = std::allocator<_Tp> > 00044 class vector 00045 : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, 00046 public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > 00047 { 00048 typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; 00049 00050 typedef typename _Base::iterator _Base_iterator; 00051 typedef typename _Base::const_iterator _Base_const_iterator; 00052 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; 00053 00054 #if __cplusplus >= 201103L 00055 typedef __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > _Safe_base; 00056 typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; 00057 #endif 00058 00059 public: 00060 typedef typename _Base::reference reference; 00061 typedef typename _Base::const_reference const_reference; 00062 00063 typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector> 00064 iterator; 00065 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector> 00066 const_iterator; 00067 00068 typedef typename _Base::size_type size_type; 00069 typedef typename _Base::difference_type difference_type; 00070 00071 typedef _Tp value_type; 00072 typedef _Allocator allocator_type; 00073 typedef typename _Base::pointer pointer; 00074 typedef typename _Base::const_pointer const_pointer; 00075 typedef std::reverse_iterator<iterator> reverse_iterator; 00076 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00077 00078 // 23.2.4.1 construct/copy/destroy: 00079 00080 vector() _GLIBCXX_NOEXCEPT 00081 : _Base(), _M_guaranteed_capacity(0) { } 00082 00083 explicit 00084 vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT 00085 : _Base(__a), _M_guaranteed_capacity(0) { } 00086 00087 #if __cplusplus >= 201103L 00088 explicit 00089 vector(size_type __n, const _Allocator& __a = _Allocator()) 00090 : _Base(__n, __a), _M_guaranteed_capacity(__n) { } 00091 00092 vector(size_type __n, const _Tp& __value, 00093 const _Allocator& __a = _Allocator()) 00094 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } 00095 #else 00096 explicit 00097 vector(size_type __n, const _Tp& __value = _Tp(), 00098 const _Allocator& __a = _Allocator()) 00099 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } 00100 #endif 00101 00102 #if __cplusplus >= 201103L 00103 template<class _InputIterator, 00104 typename = std::_RequireInputIter<_InputIterator>> 00105 #else 00106 template<class _InputIterator> 00107 #endif 00108 vector(_InputIterator __first, _InputIterator __last, 00109 const _Allocator& __a = _Allocator()) 00110 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, 00111 __last)), 00112 __gnu_debug::__base(__last), __a), 00113 _M_guaranteed_capacity(0) 00114 { _M_update_guaranteed_capacity(); } 00115 00116 vector(const vector& __x) 00117 : _Base(__x), _M_guaranteed_capacity(__x.size()) { } 00118 00119 /// Construction from a normal-mode vector 00120 vector(const _Base& __x) 00121 : _Base(__x), _M_guaranteed_capacity(__x.size()) { } 00122 00123 #if __cplusplus >= 201103L 00124 vector(vector&& __x) noexcept 00125 : _Base(std::move(__x)), 00126 _Safe_base(std::move(__x)), 00127 _M_guaranteed_capacity(this->size()) 00128 { __x._M_guaranteed_capacity = 0; } 00129 00130 vector(const vector& __x, const allocator_type& __a) 00131 : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { } 00132 00133 vector(vector&& __x, const allocator_type& __a) 00134 : _Base(std::move(__x), __a), 00135 _M_guaranteed_capacity(this->size()) 00136 { 00137 if (__x.get_allocator() == __a) 00138 this->_M_swap(__x); 00139 else 00140 __x._M_invalidate_all(); 00141 __x._M_guaranteed_capacity = 0; 00142 } 00143 00144 vector(initializer_list<value_type> __l, 00145 const allocator_type& __a = allocator_type()) 00146 : _Base(__l, __a), 00147 _M_guaranteed_capacity(__l.size()) { } 00148 #endif 00149 00150 ~vector() _GLIBCXX_NOEXCEPT { } 00151 00152 vector& 00153 operator=(const vector& __x) 00154 { 00155 _M_base() = __x; 00156 this->_M_invalidate_all(); 00157 _M_update_guaranteed_capacity(); 00158 return *this; 00159 } 00160 00161 #if __cplusplus >= 201103L 00162 vector& 00163 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 00164 { 00165 __glibcxx_check_self_move_assign(__x); 00166 bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign() 00167 || __x.get_allocator() == this->get_allocator(); 00168 _M_base() = std::move(__x._M_base()); 00169 if (__xfer_memory) 00170 this->_M_swap(__x); 00171 else 00172 this->_M_invalidate_all(); 00173 _M_update_guaranteed_capacity(); 00174 __x._M_invalidate_all(); 00175 __x._M_guaranteed_capacity = 0; 00176 return *this; 00177 } 00178 00179 vector& 00180 operator=(initializer_list<value_type> __l) 00181 { 00182 _M_base() = __l; 00183 this->_M_invalidate_all(); 00184 _M_update_guaranteed_capacity(); 00185 return *this; 00186 } 00187 #endif 00188 00189 #if __cplusplus >= 201103L 00190 template<typename _InputIterator, 00191 typename = std::_RequireInputIter<_InputIterator>> 00192 #else 00193 template<typename _InputIterator> 00194 #endif 00195 void 00196 assign(_InputIterator __first, _InputIterator __last) 00197 { 00198 __glibcxx_check_valid_range(__first, __last); 00199 _Base::assign(__gnu_debug::__base(__first), 00200 __gnu_debug::__base(__last)); 00201 this->_M_invalidate_all(); 00202 _M_update_guaranteed_capacity(); 00203 } 00204 00205 void 00206 assign(size_type __n, const _Tp& __u) 00207 { 00208 _Base::assign(__n, __u); 00209 this->_M_invalidate_all(); 00210 _M_update_guaranteed_capacity(); 00211 } 00212 00213 #if __cplusplus >= 201103L 00214 void 00215 assign(initializer_list<value_type> __l) 00216 { 00217 _Base::assign(__l); 00218 this->_M_invalidate_all(); 00219 _M_update_guaranteed_capacity(); 00220 } 00221 #endif 00222 00223 using _Base::get_allocator; 00224 00225 // iterators: 00226 iterator 00227 begin() _GLIBCXX_NOEXCEPT 00228 { return iterator(_Base::begin(), this); } 00229 00230 const_iterator 00231 begin() const _GLIBCXX_NOEXCEPT 00232 { return const_iterator(_Base::begin(), this); } 00233 00234 iterator 00235 end() _GLIBCXX_NOEXCEPT 00236 { return iterator(_Base::end(), this); } 00237 00238 const_iterator 00239 end() const _GLIBCXX_NOEXCEPT 00240 { return const_iterator(_Base::end(), this); } 00241 00242 reverse_iterator 00243 rbegin() _GLIBCXX_NOEXCEPT 00244 { return reverse_iterator(end()); } 00245 00246 const_reverse_iterator 00247 rbegin() const _GLIBCXX_NOEXCEPT 00248 { return const_reverse_iterator(end()); } 00249 00250 reverse_iterator 00251 rend() _GLIBCXX_NOEXCEPT 00252 { return reverse_iterator(begin()); } 00253 00254 const_reverse_iterator 00255 rend() const _GLIBCXX_NOEXCEPT 00256 { return const_reverse_iterator(begin()); } 00257 00258 #if __cplusplus >= 201103L 00259 const_iterator 00260 cbegin() const noexcept 00261 { return const_iterator(_Base::begin(), this); } 00262 00263 const_iterator 00264 cend() const noexcept 00265 { return const_iterator(_Base::end(), this); } 00266 00267 const_reverse_iterator 00268 crbegin() const noexcept 00269 { return const_reverse_iterator(end()); } 00270 00271 const_reverse_iterator 00272 crend() const noexcept 00273 { return const_reverse_iterator(begin()); } 00274 #endif 00275 00276 // 23.2.4.2 capacity: 00277 using _Base::size; 00278 using _Base::max_size; 00279 00280 #if __cplusplus >= 201103L 00281 void 00282 resize(size_type __sz) 00283 { 00284 bool __realloc = _M_requires_reallocation(__sz); 00285 if (__sz < this->size()) 00286 this->_M_invalidate_after_nth(__sz); 00287 _Base::resize(__sz); 00288 if (__realloc) 00289 this->_M_invalidate_all(); 00290 _M_update_guaranteed_capacity(); 00291 } 00292 00293 void 00294 resize(size_type __sz, const _Tp& __c) 00295 { 00296 bool __realloc = _M_requires_reallocation(__sz); 00297 if (__sz < this->size()) 00298 this->_M_invalidate_after_nth(__sz); 00299 _Base::resize(__sz, __c); 00300 if (__realloc) 00301 this->_M_invalidate_all(); 00302 _M_update_guaranteed_capacity(); 00303 } 00304 #else 00305 void 00306 resize(size_type __sz, _Tp __c = _Tp()) 00307 { 00308 bool __realloc = _M_requires_reallocation(__sz); 00309 if (__sz < this->size()) 00310 this->_M_invalidate_after_nth(__sz); 00311 _Base::resize(__sz, __c); 00312 if (__realloc) 00313 this->_M_invalidate_all(); 00314 _M_update_guaranteed_capacity(); 00315 } 00316 #endif 00317 00318 #if __cplusplus >= 201103L 00319 void 00320 shrink_to_fit() 00321 { 00322 if (_Base::_M_shrink_to_fit()) 00323 { 00324 _M_guaranteed_capacity = _Base::capacity(); 00325 this->_M_invalidate_all(); 00326 } 00327 } 00328 #endif 00329 00330 size_type 00331 capacity() const _GLIBCXX_NOEXCEPT 00332 { 00333 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00334 return _M_guaranteed_capacity; 00335 #else 00336 return _Base::capacity(); 00337 #endif 00338 } 00339 00340 using _Base::empty; 00341 00342 void 00343 reserve(size_type __n) 00344 { 00345 bool __realloc = _M_requires_reallocation(__n); 00346 _Base::reserve(__n); 00347 if (__n > _M_guaranteed_capacity) 00348 _M_guaranteed_capacity = __n; 00349 if (__realloc) 00350 this->_M_invalidate_all(); 00351 } 00352 00353 // element access: 00354 reference 00355 operator[](size_type __n) _GLIBCXX_NOEXCEPT 00356 { 00357 __glibcxx_check_subscript(__n); 00358 return _M_base()[__n]; 00359 } 00360 00361 const_reference 00362 operator[](size_type __n) const _GLIBCXX_NOEXCEPT 00363 { 00364 __glibcxx_check_subscript(__n); 00365 return _M_base()[__n]; 00366 } 00367 00368 using _Base::at; 00369 00370 reference 00371 front() _GLIBCXX_NOEXCEPT 00372 { 00373 __glibcxx_check_nonempty(); 00374 return _Base::front(); 00375 } 00376 00377 const_reference 00378 front() const _GLIBCXX_NOEXCEPT 00379 { 00380 __glibcxx_check_nonempty(); 00381 return _Base::front(); 00382 } 00383 00384 reference 00385 back() _GLIBCXX_NOEXCEPT 00386 { 00387 __glibcxx_check_nonempty(); 00388 return _Base::back(); 00389 } 00390 00391 const_reference 00392 back() const _GLIBCXX_NOEXCEPT 00393 { 00394 __glibcxx_check_nonempty(); 00395 return _Base::back(); 00396 } 00397 00398 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00399 // DR 464. Suggestion for new member functions in standard containers. 00400 using _Base::data; 00401 00402 // 23.2.4.3 modifiers: 00403 void 00404 push_back(const _Tp& __x) 00405 { 00406 bool __realloc = _M_requires_reallocation(this->size() + 1); 00407 _Base::push_back(__x); 00408 if (__realloc) 00409 this->_M_invalidate_all(); 00410 _M_update_guaranteed_capacity(); 00411 } 00412 00413 #if __cplusplus >= 201103L 00414 template<typename _Up = _Tp> 00415 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 00416 void>::__type 00417 push_back(_Tp&& __x) 00418 { emplace_back(std::move(__x)); } 00419 00420 template<typename... _Args> 00421 void 00422 emplace_back(_Args&&... __args) 00423 { 00424 bool __realloc = _M_requires_reallocation(this->size() + 1); 00425 _Base::emplace_back(std::forward<_Args>(__args)...); 00426 if (__realloc) 00427 this->_M_invalidate_all(); 00428 _M_update_guaranteed_capacity(); 00429 } 00430 #endif 00431 00432 void 00433 pop_back() _GLIBCXX_NOEXCEPT 00434 { 00435 __glibcxx_check_nonempty(); 00436 this->_M_invalidate_if(_Equal(--_Base::end())); 00437 _Base::pop_back(); 00438 } 00439 00440 #if __cplusplus >= 201103L 00441 template<typename... _Args> 00442 iterator 00443 emplace(const_iterator __position, _Args&&... __args) 00444 { 00445 __glibcxx_check_insert(__position); 00446 bool __realloc = _M_requires_reallocation(this->size() + 1); 00447 difference_type __offset = __position.base() - _Base::begin(); 00448 _Base_iterator __res = _Base::emplace(__position.base(), 00449 std::forward<_Args>(__args)...); 00450 if (__realloc) 00451 this->_M_invalidate_all(); 00452 else 00453 this->_M_invalidate_after_nth(__offset); 00454 _M_update_guaranteed_capacity(); 00455 return iterator(__res, this); 00456 } 00457 #endif 00458 00459 iterator 00460 #if __cplusplus >= 201103L 00461 insert(const_iterator __position, const _Tp& __x) 00462 #else 00463 insert(iterator __position, const _Tp& __x) 00464 #endif 00465 { 00466 __glibcxx_check_insert(__position); 00467 bool __realloc = _M_requires_reallocation(this->size() + 1); 00468 difference_type __offset = __position.base() - _Base::begin(); 00469 _Base_iterator __res = _Base::insert(__position.base(), __x); 00470 if (__realloc) 00471 this->_M_invalidate_all(); 00472 else 00473 this->_M_invalidate_after_nth(__offset); 00474 _M_update_guaranteed_capacity(); 00475 return iterator(__res, this); 00476 } 00477 00478 #if __cplusplus >= 201103L 00479 template<typename _Up = _Tp> 00480 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 00481 iterator>::__type 00482 insert(const_iterator __position, _Tp&& __x) 00483 { return emplace(__position, std::move(__x)); } 00484 00485 iterator 00486 insert(const_iterator __position, initializer_list<value_type> __l) 00487 { return this->insert(__position, __l.begin(), __l.end()); } 00488 #endif 00489 00490 #if __cplusplus >= 201103L 00491 iterator 00492 insert(const_iterator __position, size_type __n, const _Tp& __x) 00493 { 00494 __glibcxx_check_insert(__position); 00495 bool __realloc = _M_requires_reallocation(this->size() + __n); 00496 difference_type __offset = __position.base() - _Base::cbegin(); 00497 _Base_iterator __res = _Base::insert(__position.base(), __n, __x); 00498 if (__realloc) 00499 this->_M_invalidate_all(); 00500 else 00501 this->_M_invalidate_after_nth(__offset); 00502 _M_update_guaranteed_capacity(); 00503 return iterator(__res, this); 00504 } 00505 #else 00506 void 00507 insert(iterator __position, size_type __n, const _Tp& __x) 00508 { 00509 __glibcxx_check_insert(__position); 00510 bool __realloc = _M_requires_reallocation(this->size() + __n); 00511 difference_type __offset = __position.base() - _Base::begin(); 00512 _Base::insert(__position.base(), __n, __x); 00513 if (__realloc) 00514 this->_M_invalidate_all(); 00515 else 00516 this->_M_invalidate_after_nth(__offset); 00517 _M_update_guaranteed_capacity(); 00518 } 00519 #endif 00520 00521 #if __cplusplus >= 201103L 00522 template<class _InputIterator, 00523 typename = std::_RequireInputIter<_InputIterator>> 00524 iterator 00525 insert(const_iterator __position, 00526 _InputIterator __first, _InputIterator __last) 00527 { 00528 __glibcxx_check_insert_range(__position, __first, __last); 00529 00530 /* Hard to guess if invalidation will occur, because __last 00531 - __first can't be calculated in all cases, so we just 00532 punt here by checking if it did occur. */ 00533 _Base_iterator __old_begin = _M_base().begin(); 00534 difference_type __offset = __position.base() - _Base::cbegin(); 00535 _Base_iterator __res = _Base::insert(__position.base(), 00536 __gnu_debug::__base(__first), 00537 __gnu_debug::__base(__last)); 00538 00539 if (_M_base().begin() != __old_begin) 00540 this->_M_invalidate_all(); 00541 else 00542 this->_M_invalidate_after_nth(__offset); 00543 _M_update_guaranteed_capacity(); 00544 return iterator(__res, this); 00545 } 00546 #else 00547 template<class _InputIterator> 00548 void 00549 insert(iterator __position, 00550 _InputIterator __first, _InputIterator __last) 00551 { 00552 __glibcxx_check_insert_range(__position, __first, __last); 00553 00554 /* Hard to guess if invalidation will occur, because __last 00555 - __first can't be calculated in all cases, so we just 00556 punt here by checking if it did occur. */ 00557 _Base_iterator __old_begin = _M_base().begin(); 00558 difference_type __offset = __position.base() - _Base::begin(); 00559 _Base::insert(__position.base(), __gnu_debug::__base(__first), 00560 __gnu_debug::__base(__last)); 00561 00562 if (_M_base().begin() != __old_begin) 00563 this->_M_invalidate_all(); 00564 else 00565 this->_M_invalidate_after_nth(__offset); 00566 _M_update_guaranteed_capacity(); 00567 } 00568 #endif 00569 00570 iterator 00571 #if __cplusplus >= 201103L 00572 erase(const_iterator __position) 00573 #else 00574 erase(iterator __position) 00575 #endif 00576 { 00577 __glibcxx_check_erase(__position); 00578 difference_type __offset = __position.base() - _Base::begin(); 00579 _Base_iterator __res = _Base::erase(__position.base()); 00580 this->_M_invalidate_after_nth(__offset); 00581 return iterator(__res, this); 00582 } 00583 00584 iterator 00585 #if __cplusplus >= 201103L 00586 erase(const_iterator __first, const_iterator __last) 00587 #else 00588 erase(iterator __first, iterator __last) 00589 #endif 00590 { 00591 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00592 // 151. can't currently clear() empty container 00593 __glibcxx_check_erase_range(__first, __last); 00594 00595 if (__first.base() != __last.base()) 00596 { 00597 difference_type __offset = __first.base() - _Base::begin(); 00598 _Base_iterator __res = _Base::erase(__first.base(), 00599 __last.base()); 00600 this->_M_invalidate_after_nth(__offset); 00601 return iterator(__res, this); 00602 } 00603 else 00604 #if __cplusplus >= 201103L 00605 return begin() + (__first.base() - cbegin().base()); 00606 #else 00607 return __first; 00608 #endif 00609 } 00610 00611 void 00612 swap(vector& __x) 00613 #if __cplusplus >= 201103L 00614 noexcept(_Alloc_traits::_S_nothrow_swap()) 00615 #endif 00616 { 00617 #if __cplusplus >= 201103L 00618 if (!_Alloc_traits::_S_propagate_on_swap()) 00619 __glibcxx_check_equal_allocs(__x); 00620 #endif 00621 _Base::swap(__x); 00622 this->_M_swap(__x); 00623 std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); 00624 } 00625 00626 void 00627 clear() _GLIBCXX_NOEXCEPT 00628 { 00629 _Base::clear(); 00630 this->_M_invalidate_all(); 00631 _M_guaranteed_capacity = 0; 00632 } 00633 00634 _Base& 00635 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 00636 00637 const _Base& 00638 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 00639 00640 private: 00641 size_type _M_guaranteed_capacity; 00642 00643 bool 00644 _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT 00645 { return __elements > this->capacity(); } 00646 00647 void 00648 _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT 00649 { 00650 if (this->size() > _M_guaranteed_capacity) 00651 _M_guaranteed_capacity = this->size(); 00652 } 00653 00654 void 00655 _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT 00656 { 00657 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 00658 this->_M_invalidate_if(_After_nth(__n, _Base::begin())); 00659 } 00660 }; 00661 00662 template<typename _Tp, typename _Alloc> 00663 inline bool 00664 operator==(const vector<_Tp, _Alloc>& __lhs, 00665 const vector<_Tp, _Alloc>& __rhs) 00666 { return __lhs._M_base() == __rhs._M_base(); } 00667 00668 template<typename _Tp, typename _Alloc> 00669 inline bool 00670 operator!=(const vector<_Tp, _Alloc>& __lhs, 00671 const vector<_Tp, _Alloc>& __rhs) 00672 { return __lhs._M_base() != __rhs._M_base(); } 00673 00674 template<typename _Tp, typename _Alloc> 00675 inline bool 00676 operator<(const vector<_Tp, _Alloc>& __lhs, 00677 const vector<_Tp, _Alloc>& __rhs) 00678 { return __lhs._M_base() < __rhs._M_base(); } 00679 00680 template<typename _Tp, typename _Alloc> 00681 inline bool 00682 operator<=(const vector<_Tp, _Alloc>& __lhs, 00683 const vector<_Tp, _Alloc>& __rhs) 00684 { return __lhs._M_base() <= __rhs._M_base(); } 00685 00686 template<typename _Tp, typename _Alloc> 00687 inline bool 00688 operator>=(const vector<_Tp, _Alloc>& __lhs, 00689 const vector<_Tp, _Alloc>& __rhs) 00690 { return __lhs._M_base() >= __rhs._M_base(); } 00691 00692 template<typename _Tp, typename _Alloc> 00693 inline bool 00694 operator>(const vector<_Tp, _Alloc>& __lhs, 00695 const vector<_Tp, _Alloc>& __rhs) 00696 { return __lhs._M_base() > __rhs._M_base(); } 00697 00698 template<typename _Tp, typename _Alloc> 00699 inline void 00700 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 00701 { __lhs.swap(__rhs); } 00702 00703 } // namespace __debug 00704 00705 #if __cplusplus >= 201103L 00706 // DR 1182. 00707 /// std::hash specialization for vector<bool>. 00708 template<typename _Alloc> 00709 struct hash<__debug::vector<bool, _Alloc>> 00710 : public __hash_base<size_t, __debug::vector<bool, _Alloc>> 00711 { 00712 size_t 00713 operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept 00714 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 00715 (__b._M_base()); } 00716 }; 00717 #endif 00718 00719 } // namespace std 00720 00721 namespace __gnu_debug 00722 { 00723 template<typename _Tp, typename _Alloc> 00724 struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> > 00725 : std::__true_type 00726 { }; 00727 00728 template<typename _Alloc> 00729 struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> > 00730 : std::__false_type 00731 { }; 00732 } 00733 00734 #endif