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_SAFE_ITERATOR_H
00031 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
00032
00033 #include <debug/debug.h>
00034 #include <debug/macros.h>
00035 #include <debug/functions.h>
00036 #include <debug/formatter.h>
00037 #include <debug/safe_base.h>
00038 #include <bits/stl_pair.h>
00039 #include <ext/type_traits.h>
00040
00041 namespace __gnu_debug
00042 {
00043
00044
00045
00046
00047 inline bool
00048 __check_singular_aux(const _Safe_iterator_base* __x)
00049 { return __x->_M_singular(); }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template<typename _Iterator, typename _Sequence>
00063 class _Safe_iterator : public _Safe_iterator_base
00064 {
00065 typedef _Safe_iterator _Self;
00066
00067
00068
00069
00070 enum _Distance_precision
00071 {
00072 __dp_equality,
00073 __dp_sign,
00074 __dp_exact
00075 };
00076
00077
00078 _Iterator _M_current;
00079
00080
00081 bool
00082 _M_constant() const
00083 {
00084 typedef typename _Sequence::const_iterator const_iterator;
00085 return __is_same<const_iterator, _Safe_iterator>::value;
00086 }
00087
00088 typedef std::iterator_traits<_Iterator> _Traits;
00089
00090 public:
00091 typedef _Iterator _Base_iterator;
00092 typedef typename _Traits::iterator_category iterator_category;
00093 typedef typename _Traits::value_type value_type;
00094 typedef typename _Traits::difference_type difference_type;
00095 typedef typename _Traits::reference reference;
00096 typedef typename _Traits::pointer pointer;
00097
00098
00099 _Safe_iterator() : _M_current() { }
00100
00101
00102
00103
00104
00105
00106
00107
00108 _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
00109 : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
00110 {
00111 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00112 _M_message(__msg_init_singular)
00113 ._M_iterator(*this, "this"));
00114 }
00115
00116
00117
00118
00119 _Safe_iterator(const _Safe_iterator& __x)
00120 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
00121 {
00122
00123
00124 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
00125 || __x._M_current == _Iterator(),
00126 _M_message(__msg_init_copy_singular)
00127 ._M_iterator(*this, "this")
00128 ._M_iterator(__x, "other"));
00129 }
00130
00131
00132
00133
00134
00135 template<typename _MutableIterator>
00136 _Safe_iterator(
00137 const _Safe_iterator<_MutableIterator,
00138 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
00139 typename _Sequence::iterator::_Base_iterator>::__value),
00140 _Sequence>::__type>& __x)
00141 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
00142 {
00143
00144
00145 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
00146 || __x.base() == _Iterator(),
00147 _M_message(__msg_init_const_singular)
00148 ._M_iterator(*this, "this")
00149 ._M_iterator(__x, "other"));
00150 }
00151
00152
00153
00154
00155 _Safe_iterator&
00156 operator=(const _Safe_iterator& __x)
00157 {
00158
00159
00160 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
00161 || __x._M_current == _Iterator(),
00162 _M_message(__msg_copy_singular)
00163 ._M_iterator(*this, "this")
00164 ._M_iterator(__x, "other"));
00165 _M_current = __x._M_current;
00166 this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
00167 return *this;
00168 }
00169
00170
00171
00172
00173
00174 reference
00175 operator*() const
00176 {
00177 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00178 _M_message(__msg_bad_deref)
00179 ._M_iterator(*this, "this"));
00180 return *_M_current;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 pointer
00190 operator->() const
00191 {
00192 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00193 _M_message(__msg_bad_deref)
00194 ._M_iterator(*this, "this"));
00195 return &*_M_current;
00196 }
00197
00198
00199
00200
00201
00202
00203 _Safe_iterator&
00204 operator++()
00205 {
00206 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00207 _M_message(__msg_bad_inc)
00208 ._M_iterator(*this, "this"));
00209 ++_M_current;
00210 return *this;
00211 }
00212
00213
00214
00215
00216
00217 _Safe_iterator
00218 operator++(int)
00219 {
00220 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00221 _M_message(__msg_bad_inc)
00222 ._M_iterator(*this, "this"));
00223 _Safe_iterator __tmp(*this);
00224 ++_M_current;
00225 return __tmp;
00226 }
00227
00228
00229
00230
00231
00232
00233 _Safe_iterator&
00234 operator--()
00235 {
00236 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00237 _M_message(__msg_bad_dec)
00238 ._M_iterator(*this, "this"));
00239 --_M_current;
00240 return *this;
00241 }
00242
00243
00244
00245
00246
00247 _Safe_iterator
00248 operator--(int)
00249 {
00250 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00251 _M_message(__msg_bad_dec)
00252 ._M_iterator(*this, "this"));
00253 _Safe_iterator __tmp(*this);
00254 --_M_current;
00255 return __tmp;
00256 }
00257
00258
00259 reference
00260 operator[](const difference_type& __n) const
00261 {
00262 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
00263 && this->_M_can_advance(__n+1),
00264 _M_message(__msg_iter_subscript_oob)
00265 ._M_iterator(*this)._M_integer(__n));
00266
00267 return _M_current[__n];
00268 }
00269
00270 _Safe_iterator&
00271 operator+=(const difference_type& __n)
00272 {
00273 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
00274 _M_message(__msg_advance_oob)
00275 ._M_iterator(*this)._M_integer(__n));
00276 _M_current += __n;
00277 return *this;
00278 }
00279
00280 _Safe_iterator
00281 operator+(const difference_type& __n) const
00282 {
00283 _Safe_iterator __tmp(*this);
00284 __tmp += __n;
00285 return __tmp;
00286 }
00287
00288 _Safe_iterator&
00289 operator-=(const difference_type& __n)
00290 {
00291 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
00292 _M_message(__msg_retreat_oob)
00293 ._M_iterator(*this)._M_integer(__n));
00294 _M_current += -__n;
00295 return *this;
00296 }
00297
00298 _Safe_iterator
00299 operator-(const difference_type& __n) const
00300 {
00301 _Safe_iterator __tmp(*this);
00302 __tmp -= __n;
00303 return __tmp;
00304 }
00305
00306
00307
00308
00309
00310 _Iterator
00311 base() const { return _M_current; }
00312
00313
00314
00315
00316
00317 operator _Iterator() const { return _M_current; }
00318
00319
00320 void
00321 _M_attach(const _Sequence* __seq)
00322 {
00323 _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
00324 _M_constant());
00325 }
00326
00327
00328 void
00329 _M_attach_single(const _Sequence* __seq)
00330 {
00331 _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
00332 _M_constant());
00333 }
00334
00335
00336 void
00337 _M_invalidate();
00338
00339
00340 void
00341 _M_invalidate_single();
00342
00343
00344 bool
00345 _M_dereferenceable() const
00346 { return !this->_M_singular() && !_M_is_end(); }
00347
00348
00349 bool
00350 _M_incrementable() const { return this->_M_dereferenceable(); }
00351
00352
00353 bool
00354 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
00355
00356
00357 bool
00358 _M_can_advance(const difference_type& __n) const;
00359
00360
00361 template<typename _Other>
00362 bool
00363 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
00364
00365
00366 const _Sequence*
00367 _M_get_sequence() const
00368 { return static_cast<const _Sequence*>(_M_sequence); }
00369
00370
00371
00372
00373 template<typename _Iterator1, typename _Iterator2>
00374 static std::pair<difference_type, _Distance_precision>
00375 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
00376 {
00377 typedef typename std::iterator_traits<_Iterator1>::iterator_category
00378 _Category;
00379 return _M_get_distance(__lhs, __rhs, _Category());
00380 }
00381
00382 template<typename _Iterator1, typename _Iterator2>
00383 static std::pair<difference_type, _Distance_precision>
00384 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00385 std::random_access_iterator_tag)
00386 {
00387 return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
00388 }
00389
00390 template<typename _Iterator1, typename _Iterator2>
00391 static std::pair<difference_type, _Distance_precision>
00392 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00393 std::forward_iterator_tag)
00394 {
00395 return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
00396 __dp_equality);
00397 }
00398
00399
00400 bool _M_is_begin() const
00401 { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
00402
00403
00404 bool _M_is_end() const
00405 { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
00406 };
00407
00408 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00409 inline bool
00410 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00411 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00412 {
00413 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00414 _M_message(__msg_iter_compare_bad)
00415 ._M_iterator(__lhs, "lhs")
00416 ._M_iterator(__rhs, "rhs"));
00417 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00418 _M_message(__msg_compare_different)
00419 ._M_iterator(__lhs, "lhs")
00420 ._M_iterator(__rhs, "rhs"));
00421 return __lhs.base() == __rhs.base();
00422 }
00423
00424 template<typename _Iterator, typename _Sequence>
00425 inline bool
00426 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00427 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00428 {
00429 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00430 _M_message(__msg_iter_compare_bad)
00431 ._M_iterator(__lhs, "lhs")
00432 ._M_iterator(__rhs, "rhs"));
00433 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00434 _M_message(__msg_compare_different)
00435 ._M_iterator(__lhs, "lhs")
00436 ._M_iterator(__rhs, "rhs"));
00437 return __lhs.base() == __rhs.base();
00438 }
00439
00440 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00441 inline bool
00442 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00443 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00444 {
00445 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00446 _M_message(__msg_iter_compare_bad)
00447 ._M_iterator(__lhs, "lhs")
00448 ._M_iterator(__rhs, "rhs"));
00449 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00450 _M_message(__msg_compare_different)
00451 ._M_iterator(__lhs, "lhs")
00452 ._M_iterator(__rhs, "rhs"));
00453 return __lhs.base() != __rhs.base();
00454 }
00455
00456 template<typename _Iterator, typename _Sequence>
00457 inline bool
00458 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00459 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00460 {
00461 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00462 _M_message(__msg_iter_compare_bad)
00463 ._M_iterator(__lhs, "lhs")
00464 ._M_iterator(__rhs, "rhs"));
00465 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00466 _M_message(__msg_compare_different)
00467 ._M_iterator(__lhs, "lhs")
00468 ._M_iterator(__rhs, "rhs"));
00469 return __lhs.base() != __rhs.base();
00470 }
00471
00472 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00473 inline bool
00474 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00475 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00476 {
00477 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00478 _M_message(__msg_iter_order_bad)
00479 ._M_iterator(__lhs, "lhs")
00480 ._M_iterator(__rhs, "rhs"));
00481 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00482 _M_message(__msg_order_different)
00483 ._M_iterator(__lhs, "lhs")
00484 ._M_iterator(__rhs, "rhs"));
00485 return __lhs.base() < __rhs.base();
00486 }
00487
00488 template<typename _Iterator, typename _Sequence>
00489 inline bool
00490 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00491 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00492 {
00493 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00494 _M_message(__msg_iter_order_bad)
00495 ._M_iterator(__lhs, "lhs")
00496 ._M_iterator(__rhs, "rhs"));
00497 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00498 _M_message(__msg_order_different)
00499 ._M_iterator(__lhs, "lhs")
00500 ._M_iterator(__rhs, "rhs"));
00501 return __lhs.base() < __rhs.base();
00502 }
00503
00504 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00505 inline bool
00506 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00507 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00508 {
00509 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00510 _M_message(__msg_iter_order_bad)
00511 ._M_iterator(__lhs, "lhs")
00512 ._M_iterator(__rhs, "rhs"));
00513 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00514 _M_message(__msg_order_different)
00515 ._M_iterator(__lhs, "lhs")
00516 ._M_iterator(__rhs, "rhs"));
00517 return __lhs.base() <= __rhs.base();
00518 }
00519
00520 template<typename _Iterator, typename _Sequence>
00521 inline bool
00522 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00523 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00524 {
00525 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00526 _M_message(__msg_iter_order_bad)
00527 ._M_iterator(__lhs, "lhs")
00528 ._M_iterator(__rhs, "rhs"));
00529 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00530 _M_message(__msg_order_different)
00531 ._M_iterator(__lhs, "lhs")
00532 ._M_iterator(__rhs, "rhs"));
00533 return __lhs.base() <= __rhs.base();
00534 }
00535
00536 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00537 inline bool
00538 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00539 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00540 {
00541 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00542 _M_message(__msg_iter_order_bad)
00543 ._M_iterator(__lhs, "lhs")
00544 ._M_iterator(__rhs, "rhs"));
00545 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00546 _M_message(__msg_order_different)
00547 ._M_iterator(__lhs, "lhs")
00548 ._M_iterator(__rhs, "rhs"));
00549 return __lhs.base() > __rhs.base();
00550 }
00551
00552 template<typename _Iterator, typename _Sequence>
00553 inline bool
00554 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00555 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00556 {
00557 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00558 _M_message(__msg_iter_order_bad)
00559 ._M_iterator(__lhs, "lhs")
00560 ._M_iterator(__rhs, "rhs"));
00561 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00562 _M_message(__msg_order_different)
00563 ._M_iterator(__lhs, "lhs")
00564 ._M_iterator(__rhs, "rhs"));
00565 return __lhs.base() > __rhs.base();
00566 }
00567
00568 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00569 inline bool
00570 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00571 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00572 {
00573 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00574 _M_message(__msg_iter_order_bad)
00575 ._M_iterator(__lhs, "lhs")
00576 ._M_iterator(__rhs, "rhs"));
00577 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00578 _M_message(__msg_order_different)
00579 ._M_iterator(__lhs, "lhs")
00580 ._M_iterator(__rhs, "rhs"));
00581 return __lhs.base() >= __rhs.base();
00582 }
00583
00584 template<typename _Iterator, typename _Sequence>
00585 inline bool
00586 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00587 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00588 {
00589 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00590 _M_message(__msg_iter_order_bad)
00591 ._M_iterator(__lhs, "lhs")
00592 ._M_iterator(__rhs, "rhs"));
00593 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00594 _M_message(__msg_order_different)
00595 ._M_iterator(__lhs, "lhs")
00596 ._M_iterator(__rhs, "rhs"));
00597 return __lhs.base() >= __rhs.base();
00598 }
00599
00600
00601
00602
00603
00604 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00605 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
00606 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00607 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00608 {
00609 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00610 _M_message(__msg_distance_bad)
00611 ._M_iterator(__lhs, "lhs")
00612 ._M_iterator(__rhs, "rhs"));
00613 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00614 _M_message(__msg_distance_different)
00615 ._M_iterator(__lhs, "lhs")
00616 ._M_iterator(__rhs, "rhs"));
00617 return __lhs.base() - __rhs.base();
00618 }
00619
00620 template<typename _Iterator, typename _Sequence>
00621 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
00622 operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00623 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00624 {
00625 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00626 _M_message(__msg_distance_bad)
00627 ._M_iterator(__lhs, "lhs")
00628 ._M_iterator(__rhs, "rhs"));
00629 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00630 _M_message(__msg_distance_different)
00631 ._M_iterator(__lhs, "lhs")
00632 ._M_iterator(__rhs, "rhs"));
00633 return __lhs.base() - __rhs.base();
00634 }
00635
00636 template<typename _Iterator, typename _Sequence>
00637 inline _Safe_iterator<_Iterator, _Sequence>
00638 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
00639 const _Safe_iterator<_Iterator, _Sequence>& __i)
00640 { return __i + __n; }
00641 }
00642
00643 #ifndef _GLIBCXX_EXPORT_TEMPLATE
00644 # include <debug/safe_iterator.tcc>
00645 #endif
00646
00647 #endif