00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GLIBCXX_DEBUG_LIST
00031 #define _GLIBCXX_DEBUG_LIST 1
00032
00033 #include <list>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036
00037 namespace std
00038 {
00039 namespace __debug
00040 {
00041
00042 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
00043 class list
00044 : public _GLIBCXX_STD_D::list<_Tp, _Allocator>,
00045 public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
00046 {
00047 typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
00048 typedef __gnu_debug::_Safe_sequence<list> _Safe_base;
00049
00050 public:
00051 typedef typename _Base::reference reference;
00052 typedef typename _Base::const_reference const_reference;
00053
00054 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list>
00055 iterator;
00056 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list>
00057 const_iterator;
00058
00059 typedef typename _Base::size_type size_type;
00060 typedef typename _Base::difference_type difference_type;
00061
00062 typedef _Tp value_type;
00063 typedef _Allocator allocator_type;
00064 typedef typename _Base::pointer pointer;
00065 typedef typename _Base::const_pointer const_pointer;
00066 typedef std::reverse_iterator<iterator> reverse_iterator;
00067 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00068
00069
00070 explicit
00071 list(const _Allocator& __a = _Allocator())
00072 : _Base(__a) { }
00073
00074 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00075 explicit
00076 list(size_type __n)
00077 : _Base(__n) { }
00078
00079 list(size_type __n, const _Tp& __value,
00080 const _Allocator& __a = _Allocator())
00081 : _Base(__n, __value, __a) { }
00082 #else
00083 explicit
00084 list(size_type __n, const _Tp& __value = _Tp(),
00085 const _Allocator& __a = _Allocator())
00086 : _Base(__n, __value, __a) { }
00087 #endif
00088
00089 template<class _InputIterator>
00090 list(_InputIterator __first, _InputIterator __last,
00091 const _Allocator& __a = _Allocator())
00092 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00093 __last)),
00094 __gnu_debug::__base(__last), __a)
00095 { }
00096
00097
00098 list(const list& __x)
00099 : _Base(__x), _Safe_base() { }
00100
00101 list(const _Base& __x)
00102 : _Base(__x), _Safe_base() { }
00103
00104 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00105 list(list&& __x)
00106 : _Base(std::move(__x)), _Safe_base()
00107 { this->_M_swap(__x); }
00108
00109 list(initializer_list<value_type> __l,
00110 const allocator_type& __a = allocator_type())
00111 : _Base(__l, __a), _Safe_base() { }
00112 #endif
00113
00114 ~list() { }
00115
00116 list&
00117 operator=(const list& __x)
00118 {
00119 static_cast<_Base&>(*this) = __x;
00120 this->_M_invalidate_all();
00121 return *this;
00122 }
00123
00124 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00125 list&
00126 operator=(list&& __x)
00127 {
00128
00129
00130 clear();
00131 swap(__x);
00132 return *this;
00133 }
00134
00135 list&
00136 operator=(initializer_list<value_type> __l)
00137 {
00138 static_cast<_Base&>(*this) = __l;
00139 this->_M_invalidate_all();
00140 return *this;
00141 }
00142
00143 void
00144 assign(initializer_list<value_type> __l)
00145 {
00146 _Base::assign(__l);
00147 this->_M_invalidate_all();
00148 }
00149 #endif
00150
00151 template<class _InputIterator>
00152 void
00153 assign(_InputIterator __first, _InputIterator __last)
00154 {
00155 __glibcxx_check_valid_range(__first, __last);
00156 _Base::assign(__gnu_debug::__base(__first),
00157 __gnu_debug::__base(__last));
00158 this->_M_invalidate_all();
00159 }
00160
00161 void
00162 assign(size_type __n, const _Tp& __t)
00163 {
00164 _Base::assign(__n, __t);
00165 this->_M_invalidate_all();
00166 }
00167
00168 using _Base::get_allocator;
00169
00170
00171 iterator
00172 begin()
00173 { return iterator(_Base::begin(), this); }
00174
00175 const_iterator
00176 begin() const
00177 { return const_iterator(_Base::begin(), this); }
00178
00179 iterator
00180 end()
00181 { return iterator(_Base::end(), this); }
00182
00183 const_iterator
00184 end() const
00185 { return const_iterator(_Base::end(), this); }
00186
00187 reverse_iterator
00188 rbegin()
00189 { return reverse_iterator(end()); }
00190
00191 const_reverse_iterator
00192 rbegin() const
00193 { return const_reverse_iterator(end()); }
00194
00195 reverse_iterator
00196 rend()
00197 { return reverse_iterator(begin()); }
00198
00199 const_reverse_iterator
00200 rend() const
00201 { return const_reverse_iterator(begin()); }
00202
00203 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00204 const_iterator
00205 cbegin() const
00206 { return const_iterator(_Base::begin(), this); }
00207
00208 const_iterator
00209 cend() const
00210 { return const_iterator(_Base::end(), this); }
00211
00212 const_reverse_iterator
00213 crbegin() const
00214 { return const_reverse_iterator(end()); }
00215
00216 const_reverse_iterator
00217 crend() const
00218 { return const_reverse_iterator(begin()); }
00219 #endif
00220
00221
00222 using _Base::empty;
00223 using _Base::size;
00224 using _Base::max_size;
00225
00226 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00227 void
00228 resize(size_type __sz)
00229 {
00230 this->_M_detach_singular();
00231
00232
00233 iterator __victim = begin();
00234 iterator __end = end();
00235 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00236 ++__victim;
00237
00238 while (__victim != __end)
00239 {
00240 iterator __real_victim = __victim++;
00241 __real_victim._M_invalidate();
00242 }
00243
00244 __try
00245 {
00246 _Base::resize(__sz);
00247 }
00248 __catch(...)
00249 {
00250 this->_M_revalidate_singular();
00251 __throw_exception_again;
00252 }
00253 }
00254
00255 void
00256 resize(size_type __sz, const _Tp& __c)
00257 {
00258 this->_M_detach_singular();
00259
00260
00261 iterator __victim = begin();
00262 iterator __end = end();
00263 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00264 ++__victim;
00265
00266 while (__victim != __end)
00267 {
00268 iterator __real_victim = __victim++;
00269 __real_victim._M_invalidate();
00270 }
00271
00272 __try
00273 {
00274 _Base::resize(__sz, __c);
00275 }
00276 __catch(...)
00277 {
00278 this->_M_revalidate_singular();
00279 __throw_exception_again;
00280 }
00281 }
00282 #else
00283 void
00284 resize(size_type __sz, _Tp __c = _Tp())
00285 {
00286 this->_M_detach_singular();
00287
00288
00289 iterator __victim = begin();
00290 iterator __end = end();
00291 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00292 ++__victim;
00293
00294 while (__victim != __end)
00295 {
00296 iterator __real_victim = __victim++;
00297 __real_victim._M_invalidate();
00298 }
00299
00300 __try
00301 {
00302 _Base::resize(__sz, __c);
00303 }
00304 __catch(...)
00305 {
00306 this->_M_revalidate_singular();
00307 __throw_exception_again;
00308 }
00309 }
00310 #endif
00311
00312
00313 reference
00314 front()
00315 {
00316 __glibcxx_check_nonempty();
00317 return _Base::front();
00318 }
00319
00320 const_reference
00321 front() const
00322 {
00323 __glibcxx_check_nonempty();
00324 return _Base::front();
00325 }
00326
00327 reference
00328 back()
00329 {
00330 __glibcxx_check_nonempty();
00331 return _Base::back();
00332 }
00333
00334 const_reference
00335 back() const
00336 {
00337 __glibcxx_check_nonempty();
00338 return _Base::back();
00339 }
00340
00341
00342 using _Base::push_front;
00343
00344 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00345 using _Base::emplace_front;
00346 #endif
00347
00348 void
00349 pop_front()
00350 {
00351 __glibcxx_check_nonempty();
00352 iterator __victim = begin();
00353 __victim._M_invalidate();
00354 _Base::pop_front();
00355 }
00356
00357 using _Base::push_back;
00358
00359 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00360 using _Base::emplace_back;
00361 #endif
00362
00363 void
00364 pop_back()
00365 {
00366 __glibcxx_check_nonempty();
00367 iterator __victim = end();
00368 --__victim;
00369 __victim._M_invalidate();
00370 _Base::pop_back();
00371 }
00372
00373 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00374 template<typename... _Args>
00375 iterator
00376 emplace(iterator __position, _Args&&... __args)
00377 {
00378 __glibcxx_check_insert(__position);
00379 return iterator(_Base::emplace(__position.base(),
00380 std::forward<_Args>(__args)...), this);
00381 }
00382 #endif
00383
00384 iterator
00385 insert(iterator __position, const _Tp& __x)
00386 {
00387 __glibcxx_check_insert(__position);
00388 return iterator(_Base::insert(__position.base(), __x), this);
00389 }
00390
00391 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00392 iterator
00393 insert(iterator __position, _Tp&& __x)
00394 { return emplace(__position, std::move(__x)); }
00395
00396 void
00397 insert(iterator __p, initializer_list<value_type> __l)
00398 {
00399 __glibcxx_check_insert(__p);
00400 _Base::insert(__p, __l);
00401 }
00402 #endif
00403
00404 void
00405 insert(iterator __position, size_type __n, const _Tp& __x)
00406 {
00407 __glibcxx_check_insert(__position);
00408 _Base::insert(__position.base(), __n, __x);
00409 }
00410
00411 template<class _InputIterator>
00412 void
00413 insert(iterator __position, _InputIterator __first,
00414 _InputIterator __last)
00415 {
00416 __glibcxx_check_insert_range(__position, __first, __last);
00417 _Base::insert(__position.base(), __gnu_debug::__base(__first),
00418 __gnu_debug::__base(__last));
00419 }
00420
00421 iterator
00422 erase(iterator __position)
00423 {
00424 __glibcxx_check_erase(__position);
00425 __position._M_invalidate();
00426 return iterator(_Base::erase(__position.base()), this);
00427 }
00428
00429 iterator
00430 erase(iterator __position, iterator __last)
00431 {
00432
00433
00434 __glibcxx_check_erase_range(__position, __last);
00435 for (iterator __victim = __position; __victim != __last; )
00436 {
00437 iterator __old = __victim;
00438 ++__victim;
00439 __old._M_invalidate();
00440 }
00441 return iterator(_Base::erase(__position.base(), __last.base()), this);
00442 }
00443
00444 void
00445 swap(list& __x)
00446 {
00447 _Base::swap(__x);
00448 this->_M_swap(__x);
00449 }
00450
00451 void
00452 clear()
00453 {
00454 _Base::clear();
00455 this->_M_invalidate_all();
00456 }
00457
00458
00459 void
00460 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00461 splice(iterator __position, list&& __x)
00462 #else
00463 splice(iterator __position, list& __x)
00464 #endif
00465 {
00466 _GLIBCXX_DEBUG_VERIFY(&__x != this,
00467 _M_message(__gnu_debug::__msg_self_splice)
00468 ._M_sequence(*this, "this"));
00469 this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end());
00470 }
00471
00472 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00473 void
00474 splice(iterator __position, list& __x)
00475 { splice(__position, std::move(__x)); }
00476 #endif
00477
00478 void
00479 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00480 splice(iterator __position, list&& __x, iterator __i)
00481 #else
00482 splice(iterator __position, list& __x, iterator __i)
00483 #endif
00484 {
00485 __glibcxx_check_insert(__position);
00486
00487
00488
00489
00490 _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
00491 _M_message(__gnu_debug::__msg_splice_bad)
00492 ._M_iterator(__i, "__i"));
00493 _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
00494 _M_message(__gnu_debug::__msg_splice_other)
00495 ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
00496
00497
00498
00499 this->_M_transfer_iter(__i);
00500 _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00501 __i.base());
00502 }
00503
00504 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00505 void
00506 splice(iterator __position, list& __x, iterator __i)
00507 { splice(__position, std::move(__x), __i); }
00508 #endif
00509
00510 void
00511 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00512 splice(iterator __position, list&& __x, iterator __first,
00513 iterator __last)
00514 #else
00515 splice(iterator __position, list& __x, iterator __first,
00516 iterator __last)
00517 #endif
00518 {
00519 __glibcxx_check_insert(__position);
00520 __glibcxx_check_valid_range(__first, __last);
00521 _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
00522 _M_message(__gnu_debug::__msg_splice_other)
00523 ._M_sequence(__x, "x")
00524 ._M_iterator(__first, "first"));
00525
00526
00527
00528
00529 for (iterator __tmp = __first; __tmp != __last; )
00530 {
00531 _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
00532 _M_message(__gnu_debug::__msg_splice_overlap)
00533 ._M_iterator(__tmp, "position")
00534 ._M_iterator(__first, "first")
00535 ._M_iterator(__last, "last"));
00536 iterator __victim = __tmp++;
00537
00538
00539 this->_M_transfer_iter(__victim);
00540 }
00541
00542 _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00543 __first.base(), __last.base());
00544 }
00545
00546 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00547 void
00548 splice(iterator __position, list& __x, iterator __first, iterator __last)
00549 { splice(__position, std::move(__x), __first, __last); }
00550 #endif
00551
00552 void
00553 remove(const _Tp& __value)
00554 {
00555 for (iterator __x = begin(); __x.base() != _Base::end(); )
00556 {
00557 if (*__x == __value)
00558 __x = erase(__x);
00559 else
00560 ++__x;
00561 }
00562 }
00563
00564 template<class _Predicate>
00565 void
00566 remove_if(_Predicate __pred)
00567 {
00568 for (iterator __x = begin(); __x.base() != _Base::end(); )
00569 {
00570 if (__pred(*__x))
00571 __x = erase(__x);
00572 else
00573 ++__x;
00574 }
00575 }
00576
00577 void
00578 unique()
00579 {
00580 iterator __first = begin();
00581 iterator __last = end();
00582 if (__first == __last)
00583 return;
00584 iterator __next = __first;
00585 while (++__next != __last)
00586 {
00587 if (*__first == *__next)
00588 erase(__next);
00589 else
00590 __first = __next;
00591 __next = __first;
00592 }
00593 }
00594
00595 template<class _BinaryPredicate>
00596 void
00597 unique(_BinaryPredicate __binary_pred)
00598 {
00599 iterator __first = begin();
00600 iterator __last = end();
00601 if (__first == __last)
00602 return;
00603 iterator __next = __first;
00604 while (++__next != __last)
00605 {
00606 if (__binary_pred(*__first, *__next))
00607 erase(__next);
00608 else
00609 __first = __next;
00610 __next = __first;
00611 }
00612 }
00613
00614 void
00615 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00616 merge(list&& __x)
00617 #else
00618 merge(list& __x)
00619 #endif
00620 {
00621
00622
00623 if (this != &__x)
00624 {
00625 __glibcxx_check_sorted(_Base::begin(), _Base::end());
00626 __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
00627 for (iterator __tmp = __x.begin(); __tmp != __x.end();)
00628 {
00629 iterator __victim = __tmp++;
00630 this->_M_transfer_iter(__victim);
00631 }
00632 _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
00633 }
00634 }
00635
00636 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00637 void
00638 merge(list& __x)
00639 { merge(std::move(__x)); }
00640 #endif
00641
00642 template<class _Compare>
00643 void
00644 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00645 merge(list&& __x, _Compare __comp)
00646 #else
00647 merge(list& __x, _Compare __comp)
00648 #endif
00649 {
00650
00651
00652 if (this != &__x)
00653 {
00654 __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
00655 __comp);
00656 __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
00657 __comp);
00658 for (iterator __tmp = __x.begin(); __tmp != __x.end();)
00659 {
00660 iterator __victim = __tmp++;
00661 this->_M_transfer_iter(__victim);
00662 }
00663 _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
00664 }
00665 }
00666
00667 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00668 template<typename _Compare>
00669 void
00670 merge(list& __x, _Compare __comp)
00671 { merge(std::move(__x), __comp); }
00672 #endif
00673
00674 void
00675 sort() { _Base::sort(); }
00676
00677 template<typename _StrictWeakOrdering>
00678 void
00679 sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
00680
00681 using _Base::reverse;
00682
00683 _Base&
00684 _M_base() { return *this; }
00685
00686 const _Base&
00687 _M_base() const { return *this; }
00688
00689 private:
00690 void
00691 _M_invalidate_all()
00692 {
00693 typedef typename _Base::const_iterator _Base_const_iterator;
00694 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00695 this->_M_invalidate_if(_Not_equal(_M_base().end()));
00696 }
00697 };
00698
00699 template<typename _Tp, typename _Alloc>
00700 inline bool
00701 operator==(const list<_Tp, _Alloc>& __lhs,
00702 const list<_Tp, _Alloc>& __rhs)
00703 { return __lhs._M_base() == __rhs._M_base(); }
00704
00705 template<typename _Tp, typename _Alloc>
00706 inline bool
00707 operator!=(const list<_Tp, _Alloc>& __lhs,
00708 const list<_Tp, _Alloc>& __rhs)
00709 { return __lhs._M_base() != __rhs._M_base(); }
00710
00711 template<typename _Tp, typename _Alloc>
00712 inline bool
00713 operator<(const list<_Tp, _Alloc>& __lhs,
00714 const list<_Tp, _Alloc>& __rhs)
00715 { return __lhs._M_base() < __rhs._M_base(); }
00716
00717 template<typename _Tp, typename _Alloc>
00718 inline bool
00719 operator<=(const list<_Tp, _Alloc>& __lhs,
00720 const list<_Tp, _Alloc>& __rhs)
00721 { return __lhs._M_base() <= __rhs._M_base(); }
00722
00723 template<typename _Tp, typename _Alloc>
00724 inline bool
00725 operator>=(const list<_Tp, _Alloc>& __lhs,
00726 const list<_Tp, _Alloc>& __rhs)
00727 { return __lhs._M_base() >= __rhs._M_base(); }
00728
00729 template<typename _Tp, typename _Alloc>
00730 inline bool
00731 operator>(const list<_Tp, _Alloc>& __lhs,
00732 const list<_Tp, _Alloc>& __rhs)
00733 { return __lhs._M_base() > __rhs._M_base(); }
00734
00735 template<typename _Tp, typename _Alloc>
00736 inline void
00737 swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
00738 { __lhs.swap(__rhs); }
00739
00740 }
00741 }
00742
00743 #endif