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