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