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