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