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