libstdc++
|
00001 // Debugging vector implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003-2016 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 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00251 __glibcxx_check_valid_range2(__first, __last, __dist); 00252 00253 if (__dist.second >= __gnu_debug::__dp_sign) 00254 _Base::assign(__gnu_debug::__unsafe(__first), 00255 __gnu_debug::__unsafe(__last)); 00256 else 00257 _Base::assign(__first, __last); 00258 00259 this->_M_invalidate_all(); 00260 this->_M_update_guaranteed_capacity(); 00261 } 00262 00263 void 00264 assign(size_type __n, const _Tp& __u) 00265 { 00266 _Base::assign(__n, __u); 00267 this->_M_invalidate_all(); 00268 this->_M_update_guaranteed_capacity(); 00269 } 00270 00271 #if __cplusplus >= 201103L 00272 void 00273 assign(initializer_list<value_type> __l) 00274 { 00275 _Base::assign(__l); 00276 this->_M_invalidate_all(); 00277 this->_M_update_guaranteed_capacity(); 00278 } 00279 #endif 00280 00281 using _Base::get_allocator; 00282 00283 // iterators: 00284 iterator 00285 begin() _GLIBCXX_NOEXCEPT 00286 { return iterator(_Base::begin(), this); } 00287 00288 const_iterator 00289 begin() const _GLIBCXX_NOEXCEPT 00290 { return const_iterator(_Base::begin(), this); } 00291 00292 iterator 00293 end() _GLIBCXX_NOEXCEPT 00294 { return iterator(_Base::end(), this); } 00295 00296 const_iterator 00297 end() const _GLIBCXX_NOEXCEPT 00298 { return const_iterator(_Base::end(), this); } 00299 00300 reverse_iterator 00301 rbegin() _GLIBCXX_NOEXCEPT 00302 { return reverse_iterator(end()); } 00303 00304 const_reverse_iterator 00305 rbegin() const _GLIBCXX_NOEXCEPT 00306 { return const_reverse_iterator(end()); } 00307 00308 reverse_iterator 00309 rend() _GLIBCXX_NOEXCEPT 00310 { return reverse_iterator(begin()); } 00311 00312 const_reverse_iterator 00313 rend() const _GLIBCXX_NOEXCEPT 00314 { return const_reverse_iterator(begin()); } 00315 00316 #if __cplusplus >= 201103L 00317 const_iterator 00318 cbegin() const noexcept 00319 { return const_iterator(_Base::begin(), this); } 00320 00321 const_iterator 00322 cend() const noexcept 00323 { return const_iterator(_Base::end(), this); } 00324 00325 const_reverse_iterator 00326 crbegin() const noexcept 00327 { return const_reverse_iterator(end()); } 00328 00329 const_reverse_iterator 00330 crend() const noexcept 00331 { return const_reverse_iterator(begin()); } 00332 #endif 00333 00334 // 23.2.4.2 capacity: 00335 using _Base::size; 00336 using _Base::max_size; 00337 00338 #if __cplusplus >= 201103L 00339 void 00340 resize(size_type __sz) 00341 { 00342 bool __realloc = this->_M_requires_reallocation(__sz); 00343 if (__sz < this->size()) 00344 this->_M_invalidate_after_nth(__sz); 00345 _Base::resize(__sz); 00346 if (__realloc) 00347 this->_M_invalidate_all(); 00348 this->_M_update_guaranteed_capacity(); 00349 } 00350 00351 void 00352 resize(size_type __sz, const _Tp& __c) 00353 { 00354 bool __realloc = this->_M_requires_reallocation(__sz); 00355 if (__sz < this->size()) 00356 this->_M_invalidate_after_nth(__sz); 00357 _Base::resize(__sz, __c); 00358 if (__realloc) 00359 this->_M_invalidate_all(); 00360 this->_M_update_guaranteed_capacity(); 00361 } 00362 #else 00363 void 00364 resize(size_type __sz, _Tp __c = _Tp()) 00365 { 00366 bool __realloc = this->_M_requires_reallocation(__sz); 00367 if (__sz < this->size()) 00368 this->_M_invalidate_after_nth(__sz); 00369 _Base::resize(__sz, __c); 00370 if (__realloc) 00371 this->_M_invalidate_all(); 00372 this->_M_update_guaranteed_capacity(); 00373 } 00374 #endif 00375 00376 #if __cplusplus >= 201103L 00377 void 00378 shrink_to_fit() 00379 { 00380 if (_Base::_M_shrink_to_fit()) 00381 { 00382 this->_M_guaranteed_capacity = _Base::capacity(); 00383 this->_M_invalidate_all(); 00384 } 00385 } 00386 #endif 00387 00388 size_type 00389 capacity() const _GLIBCXX_NOEXCEPT 00390 { 00391 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00392 return this->_M_guaranteed_capacity; 00393 #else 00394 return _Base::capacity(); 00395 #endif 00396 } 00397 00398 using _Base::empty; 00399 00400 void 00401 reserve(size_type __n) 00402 { 00403 bool __realloc = this->_M_requires_reallocation(__n); 00404 _Base::reserve(__n); 00405 if (__n > this->_M_guaranteed_capacity) 00406 this->_M_guaranteed_capacity = __n; 00407 if (__realloc) 00408 this->_M_invalidate_all(); 00409 } 00410 00411 // element access: 00412 reference 00413 operator[](size_type __n) _GLIBCXX_NOEXCEPT 00414 { 00415 __glibcxx_check_subscript(__n); 00416 return _M_base()[__n]; 00417 } 00418 00419 const_reference 00420 operator[](size_type __n) const _GLIBCXX_NOEXCEPT 00421 { 00422 __glibcxx_check_subscript(__n); 00423 return _M_base()[__n]; 00424 } 00425 00426 using _Base::at; 00427 00428 reference 00429 front() _GLIBCXX_NOEXCEPT 00430 { 00431 __glibcxx_check_nonempty(); 00432 return _Base::front(); 00433 } 00434 00435 const_reference 00436 front() const _GLIBCXX_NOEXCEPT 00437 { 00438 __glibcxx_check_nonempty(); 00439 return _Base::front(); 00440 } 00441 00442 reference 00443 back() _GLIBCXX_NOEXCEPT 00444 { 00445 __glibcxx_check_nonempty(); 00446 return _Base::back(); 00447 } 00448 00449 const_reference 00450 back() const _GLIBCXX_NOEXCEPT 00451 { 00452 __glibcxx_check_nonempty(); 00453 return _Base::back(); 00454 } 00455 00456 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00457 // DR 464. Suggestion for new member functions in standard containers. 00458 using _Base::data; 00459 00460 // 23.2.4.3 modifiers: 00461 void 00462 push_back(const _Tp& __x) 00463 { 00464 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 00465 _Base::push_back(__x); 00466 if (__realloc) 00467 this->_M_invalidate_all(); 00468 this->_M_update_guaranteed_capacity(); 00469 } 00470 00471 #if __cplusplus >= 201103L 00472 template<typename _Up = _Tp> 00473 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 00474 void>::__type 00475 push_back(_Tp&& __x) 00476 { emplace_back(std::move(__x)); } 00477 00478 template<typename... _Args> 00479 void 00480 emplace_back(_Args&&... __args) 00481 { 00482 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 00483 _Base::emplace_back(std::forward<_Args>(__args)...); 00484 if (__realloc) 00485 this->_M_invalidate_all(); 00486 this->_M_update_guaranteed_capacity(); 00487 } 00488 #endif 00489 00490 void 00491 pop_back() _GLIBCXX_NOEXCEPT 00492 { 00493 __glibcxx_check_nonempty(); 00494 this->_M_invalidate_if(_Equal(--_Base::end())); 00495 _Base::pop_back(); 00496 } 00497 00498 #if __cplusplus >= 201103L 00499 template<typename... _Args> 00500 iterator 00501 emplace(const_iterator __position, _Args&&... __args) 00502 { 00503 __glibcxx_check_insert(__position); 00504 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 00505 difference_type __offset = __position.base() - _Base::begin(); 00506 _Base_iterator __res = _Base::emplace(__position.base(), 00507 std::forward<_Args>(__args)...); 00508 if (__realloc) 00509 this->_M_invalidate_all(); 00510 else 00511 this->_M_invalidate_after_nth(__offset); 00512 this->_M_update_guaranteed_capacity(); 00513 return iterator(__res, this); 00514 } 00515 #endif 00516 00517 iterator 00518 #if __cplusplus >= 201103L 00519 insert(const_iterator __position, const _Tp& __x) 00520 #else 00521 insert(iterator __position, const _Tp& __x) 00522 #endif 00523 { 00524 __glibcxx_check_insert(__position); 00525 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 00526 difference_type __offset = __position.base() - _Base::begin(); 00527 _Base_iterator __res = _Base::insert(__position.base(), __x); 00528 if (__realloc) 00529 this->_M_invalidate_all(); 00530 else 00531 this->_M_invalidate_after_nth(__offset); 00532 this->_M_update_guaranteed_capacity(); 00533 return iterator(__res, this); 00534 } 00535 00536 #if __cplusplus >= 201103L 00537 template<typename _Up = _Tp> 00538 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 00539 iterator>::__type 00540 insert(const_iterator __position, _Tp&& __x) 00541 { return emplace(__position, std::move(__x)); } 00542 00543 iterator 00544 insert(const_iterator __position, initializer_list<value_type> __l) 00545 { return this->insert(__position, __l.begin(), __l.end()); } 00546 #endif 00547 00548 #if __cplusplus >= 201103L 00549 iterator 00550 insert(const_iterator __position, size_type __n, const _Tp& __x) 00551 { 00552 __glibcxx_check_insert(__position); 00553 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 00554 difference_type __offset = __position.base() - _Base::cbegin(); 00555 _Base_iterator __res = _Base::insert(__position.base(), __n, __x); 00556 if (__realloc) 00557 this->_M_invalidate_all(); 00558 else 00559 this->_M_invalidate_after_nth(__offset); 00560 this->_M_update_guaranteed_capacity(); 00561 return iterator(__res, this); 00562 } 00563 #else 00564 void 00565 insert(iterator __position, size_type __n, const _Tp& __x) 00566 { 00567 __glibcxx_check_insert(__position); 00568 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 00569 difference_type __offset = __position.base() - _Base::begin(); 00570 _Base::insert(__position.base(), __n, __x); 00571 if (__realloc) 00572 this->_M_invalidate_all(); 00573 else 00574 this->_M_invalidate_after_nth(__offset); 00575 this->_M_update_guaranteed_capacity(); 00576 } 00577 #endif 00578 00579 #if __cplusplus >= 201103L 00580 template<class _InputIterator, 00581 typename = std::_RequireInputIter<_InputIterator>> 00582 iterator 00583 insert(const_iterator __position, 00584 _InputIterator __first, _InputIterator __last) 00585 { 00586 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00587 __glibcxx_check_insert_range(__position, __first, __last, __dist); 00588 00589 /* Hard to guess if invalidation will occur, because __last 00590 - __first can't be calculated in all cases, so we just 00591 punt here by checking if it did occur. */ 00592 _Base_iterator __old_begin = _M_base().begin(); 00593 difference_type __offset = __position.base() - _Base::cbegin(); 00594 _Base_iterator __res; 00595 if (__dist.second >= __gnu_debug::__dp_sign) 00596 __res = _Base::insert(__position.base(), 00597 __gnu_debug::__unsafe(__first), 00598 __gnu_debug::__unsafe(__last)); 00599 else 00600 __res = _Base::insert(__position.base(), __first, __last); 00601 00602 if (_M_base().begin() != __old_begin) 00603 this->_M_invalidate_all(); 00604 else 00605 this->_M_invalidate_after_nth(__offset); 00606 this->_M_update_guaranteed_capacity(); 00607 return iterator(__res, this); 00608 } 00609 #else 00610 template<class _InputIterator> 00611 void 00612 insert(iterator __position, 00613 _InputIterator __first, _InputIterator __last) 00614 { 00615 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00616 __glibcxx_check_insert_range(__position, __first, __last, __dist); 00617 00618 /* Hard to guess if invalidation will occur, because __last 00619 - __first can't be calculated in all cases, so we just 00620 punt here by checking if it did occur. */ 00621 _Base_iterator __old_begin = _M_base().begin(); 00622 difference_type __offset = __position.base() - _Base::begin(); 00623 if (__dist.second >= __gnu_debug::__dp_sign) 00624 _Base::insert(__position.base(), __gnu_debug::__unsafe(__first), 00625 __gnu_debug::__unsafe(__last)); 00626 else 00627 _Base::insert(__position.base(), __first, __last); 00628 00629 if (_M_base().begin() != __old_begin) 00630 this->_M_invalidate_all(); 00631 else 00632 this->_M_invalidate_after_nth(__offset); 00633 this->_M_update_guaranteed_capacity(); 00634 } 00635 #endif 00636 00637 iterator 00638 #if __cplusplus >= 201103L 00639 erase(const_iterator __position) 00640 #else 00641 erase(iterator __position) 00642 #endif 00643 { 00644 __glibcxx_check_erase(__position); 00645 difference_type __offset = __position.base() - _Base::begin(); 00646 _Base_iterator __res = _Base::erase(__position.base()); 00647 this->_M_invalidate_after_nth(__offset); 00648 return iterator(__res, this); 00649 } 00650 00651 iterator 00652 #if __cplusplus >= 201103L 00653 erase(const_iterator __first, const_iterator __last) 00654 #else 00655 erase(iterator __first, iterator __last) 00656 #endif 00657 { 00658 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00659 // 151. can't currently clear() empty container 00660 __glibcxx_check_erase_range(__first, __last); 00661 00662 if (__first.base() != __last.base()) 00663 { 00664 difference_type __offset = __first.base() - _Base::begin(); 00665 _Base_iterator __res = _Base::erase(__first.base(), 00666 __last.base()); 00667 this->_M_invalidate_after_nth(__offset); 00668 return iterator(__res, this); 00669 } 00670 else 00671 #if __cplusplus >= 201103L 00672 return begin() + (__first.base() - cbegin().base()); 00673 #else 00674 return __first; 00675 #endif 00676 } 00677 00678 void 00679 swap(vector& __x) 00680 _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) 00681 { 00682 _Safe::_M_swap(__x); 00683 _Base::swap(__x); 00684 std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity); 00685 } 00686 00687 void 00688 clear() _GLIBCXX_NOEXCEPT 00689 { 00690 _Base::clear(); 00691 this->_M_invalidate_all(); 00692 } 00693 00694 _Base& 00695 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 00696 00697 const _Base& 00698 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 00699 00700 private: 00701 void 00702 _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT 00703 { 00704 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 00705 this->_M_invalidate_if(_After_nth(__n, _Base::begin())); 00706 } 00707 }; 00708 00709 template<typename _Tp, typename _Alloc> 00710 inline bool 00711 operator==(const vector<_Tp, _Alloc>& __lhs, 00712 const vector<_Tp, _Alloc>& __rhs) 00713 { return __lhs._M_base() == __rhs._M_base(); } 00714 00715 template<typename _Tp, typename _Alloc> 00716 inline bool 00717 operator!=(const vector<_Tp, _Alloc>& __lhs, 00718 const vector<_Tp, _Alloc>& __rhs) 00719 { return __lhs._M_base() != __rhs._M_base(); } 00720 00721 template<typename _Tp, typename _Alloc> 00722 inline bool 00723 operator<(const vector<_Tp, _Alloc>& __lhs, 00724 const vector<_Tp, _Alloc>& __rhs) 00725 { return __lhs._M_base() < __rhs._M_base(); } 00726 00727 template<typename _Tp, typename _Alloc> 00728 inline bool 00729 operator<=(const vector<_Tp, _Alloc>& __lhs, 00730 const vector<_Tp, _Alloc>& __rhs) 00731 { return __lhs._M_base() <= __rhs._M_base(); } 00732 00733 template<typename _Tp, typename _Alloc> 00734 inline bool 00735 operator>=(const vector<_Tp, _Alloc>& __lhs, 00736 const vector<_Tp, _Alloc>& __rhs) 00737 { return __lhs._M_base() >= __rhs._M_base(); } 00738 00739 template<typename _Tp, typename _Alloc> 00740 inline bool 00741 operator>(const vector<_Tp, _Alloc>& __lhs, 00742 const vector<_Tp, _Alloc>& __rhs) 00743 { return __lhs._M_base() > __rhs._M_base(); } 00744 00745 template<typename _Tp, typename _Alloc> 00746 inline void 00747 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 00748 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) 00749 { __lhs.swap(__rhs); } 00750 00751 } // namespace __debug 00752 00753 #if __cplusplus >= 201103L 00754 // DR 1182. 00755 /// std::hash specialization for vector<bool>. 00756 template<typename _Alloc> 00757 struct hash<__debug::vector<bool, _Alloc>> 00758 : public __hash_base<size_t, __debug::vector<bool, _Alloc>> 00759 { 00760 size_t 00761 operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept 00762 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); } 00763 }; 00764 #endif 00765 00766 } // namespace std 00767 00768 namespace __gnu_debug 00769 { 00770 template<typename _Tp, typename _Alloc> 00771 struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> > 00772 : std::__true_type 00773 { }; 00774 00775 template<typename _Alloc> 00776 struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> > 00777 : std::__false_type 00778 { }; 00779 } 00780 00781 #endif