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