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