/home/ntakagi/work/STLport-5.1.5/stlport/stl/debug/_iterator.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 1997
00004  * Moscow Center for SPARC Technology
00005  *
00006  * Copyright (c) 1999
00007  * Boris Fomitchev
00008  *
00009  * This material is provided "as is", with absolutely no warranty expressed
00010  * or implied. Any use is at your own risk.
00011  *
00012  * Permission to use or copy this software for any purpose is hereby granted
00013  * without fee, provided the above notices are retained on all copies.
00014  * Permission to modify the code and to distribute modified code is granted,
00015  * provided the above notices are retained, and a notice that the code was
00016  * modified is included with the above copyright notice.
00017  *
00018  */
00019 
00020 #ifndef _STLP_DBG_ITERATOR_H
00021 #define _STLP_DBG_ITERATOR_H
00022 
00023 #ifndef _STLP_INTERNAL_PAIR_H
00024 #  include <stl/_pair.h>
00025 #endif
00026 
00027 #ifndef _STLP_INTERNAL_ALLOC_H
00028 #  include <stl/_alloc.h>
00029 #endif
00030 
00031 #define _STLP_DBG_ALLOCATOR_SELECT( _Tp ) _STLP_DEFAULT_ALLOCATOR_SELECT( _Tp )
00032 
00033 _STLP_BEGIN_NAMESPACE
00034 
00035 _STLP_MOVE_TO_PRIV_NAMESPACE
00036 
00037 //============================================================
00038 
00039 template <class _Iterator>
00040 void _Decrement(_Iterator& __it, const bidirectional_iterator_tag &)
00041 { --__it; }
00042 
00043 template <class _Iterator>
00044 void _Decrement(_Iterator& __it, const random_access_iterator_tag &)
00045 { --__it; }
00046 
00047 template <class _Iterator>
00048 void _Decrement(_Iterator& __it, const forward_iterator_tag &)
00049 { _STLP_ASSERT(0) }
00050 
00051 template <class _Iterator>
00052 void _Advance(_Iterator&, ptrdiff_t, const forward_iterator_tag &)
00053 { _STLP_ASSERT(0) }
00054 
00055 template <class _Iterator>
00056 void _Advance(_Iterator& __it, ptrdiff_t, const bidirectional_iterator_tag &)
00057 { _STLP_ASSERT(0) }
00058 
00059 template <class _Iterator>
00060 void _Advance(_Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &)
00061 { __it += __n; }
00062 
00063 template <class _Iterator>
00064 ptrdiff_t _DBG_distance(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
00065 { return __x - __y; }
00066 
00067 template <class _Iterator>
00068 ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
00069   _STLP_ASSERT(0)
00070   return 0;
00071 }
00072 
00073 template <class _Iterator>
00074 ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
00075   _STLP_ASSERT(0)
00076   return 0;
00077 }
00078 
00079 template <class _Iterator>
00080 bool _CompareIt(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
00081   _STLP_ASSERT(0)
00082   return false;
00083 }
00084 
00085 template <class _Iterator>
00086 bool _CompareIt(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
00087   _STLP_ASSERT(0)
00088   return false;
00089 }
00090 
00091 template <class _Iterator>
00092 bool _CompareIt(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
00093 { return __x < __y; }
00094 
00095 template <class _Iterator>
00096 bool _Dereferenceable(const _Iterator& __it)
00097 { return (__it._Get_container_ptr() != 0) && !(__it._M_iterator == (__it._Get_container_ptr())->end()); }
00098 
00099 template <class _Iterator>
00100 bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const forward_iterator_tag &)
00101 { return (__n == 1) && _Dereferenceable(__it); }
00102 
00103 template <class _Iterator>
00104 bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const bidirectional_iterator_tag &) {
00105   typedef typename _Iterator::_Container_type __container_type;
00106   __container_type* __c = __it._Get_container_ptr();
00107   return (__c != 0) && ((__n == 1 && __it._M_iterator != __c->end() ) ||
00108                         (__n == -1 && __it._M_iterator != __c->begin()));
00109 }
00110 
00111 template <class _Iterator>
00112 bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &) {
00113   typedef typename _Iterator::_Container_type __container_type;
00114   __container_type* __c = __it._Get_container_ptr();
00115   if (__c == 0) return false;
00116   ptrdiff_t __new_pos = (__it._M_iterator - __c->begin()) + __n;
00117   return  (__new_pos >= 0) && (__STATIC_CAST(typename __container_type::size_type, __new_pos) <= __c->size());
00118 }
00119 
00120 
00121 template <class _Container>
00122 struct _DBG_iter_base : public __owned_link {
00123 public:
00124   typedef typename _Container::value_type value_type;
00125   typedef typename _Container::reference  reference;
00126   typedef typename _Container::pointer    pointer;
00127   typedef ptrdiff_t difference_type;
00128   //private:
00129   typedef typename _Container::iterator        _Nonconst_iterator;
00130   typedef typename _Container::const_iterator  _Const_iterator;
00131   typedef _Container                     _Container_type;
00132 
00133 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00134   typedef typename iterator_traits<_Const_iterator>::iterator_category _Iterator_category;
00135 #else
00136   typedef typename _Container::_Iterator_category  _Iterator_category;
00137 #endif
00138   typedef _Iterator_category iterator_category;
00139 
00140   _DBG_iter_base() : __owned_link(0)  {}
00141   _DBG_iter_base(const __owned_list* __c, const _Const_iterator& __it) :
00142 #if defined(__HP_aCC) && (__HP_aCC < 60000)
00143   __owned_link(__c), _M_iterator(*__REINTERPRET_CAST(const _Nonconst_iterator *, &__it)) {}
00144 #else
00145     __owned_link(__c), _M_iterator(*(const _Nonconst_iterator*)&__it) {}
00146 #endif
00147   _Container* _Get_container_ptr() const {
00148     return (_Container*)__stl_debugger::_Get_container_ptr(this);
00149   }
00150 
00151   void __increment();
00152   void __decrement();
00153   void __advance(ptrdiff_t __n);
00154 
00155 // protected:
00156   _Nonconst_iterator _M_iterator;
00157 };
00158 
00159 template <class _Container>
00160 inline void _DBG_iter_base<_Container>::__increment() {
00161   _STLP_DEBUG_CHECK(_Incrementable(*this, 1, _Iterator_category()))
00162   ++_M_iterator;
00163 }
00164 
00165 template <class _Container>
00166 inline void _DBG_iter_base<_Container>::__decrement() {
00167   _STLP_DEBUG_CHECK(_Incrementable(*this, -1, _Iterator_category()))
00168   _Decrement(_M_iterator, _Iterator_category());
00169 }
00170 
00171 template <class _Container>
00172 inline void _DBG_iter_base<_Container>::__advance(ptrdiff_t __n) {
00173   _STLP_DEBUG_CHECK(_Incrementable(*this, __n, _Iterator_category()))
00174   _Advance(_M_iterator, __n, _Iterator_category());
00175 }
00176 
00177 template <class _Container>
00178 ptrdiff_t operator-(const _DBG_iter_base<_Container>& __x,
00179                     const _DBG_iter_base<_Container>& __y ) {
00180   typedef typename _DBG_iter_base<_Container>::_Iterator_category  _Iterator_category;
00181   _STLP_DEBUG_CHECK(__check_same_owner(__x, __y))
00182   return _DBG_distance(__x._M_iterator,__y._M_iterator, _Iterator_category());
00183 }
00184 
00185 template <class _Container, class _Traits>
00186 struct _DBG_iter_mid : public _DBG_iter_base<_Container> {
00187   typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_self;
00188   typedef typename _Container::iterator        _Nonconst_iterator;
00189   typedef typename _Container::const_iterator  _Const_iterator;
00190 
00191   _DBG_iter_mid() {}
00192 
00193   explicit _DBG_iter_mid(const _Nonconst_self& __it) :
00194       _DBG_iter_base<_Container>(__it) {}
00195 
00196   _DBG_iter_mid(const __owned_list* __c, const _Const_iterator& __it) :
00197       _DBG_iter_base<_Container>(__c, __it) {}
00198 };
00199 
00200 template <class _Container, class _Traits>
00201 struct _DBG_iter : public _DBG_iter_mid<_Container, _Traits> {
00202   typedef _DBG_iter_base<_Container>          _Base;
00203 public:
00204   typedef typename _Base::value_type value_type;
00205   typedef typename _Base::difference_type difference_type;
00206   typedef typename _Traits::reference  reference;
00207   typedef typename _Traits::pointer    pointer;
00208 
00209   typedef typename _Base::_Nonconst_iterator _Nonconst_iterator;
00210   typedef typename _Base::_Const_iterator _Const_iterator;
00211 
00212 private:
00213   typedef _DBG_iter<_Container, _Traits>     _Self;
00214   typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_mid;
00215 
00216 public:
00217 
00218 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00219   typedef typename _Base::iterator_category iterator_category;
00220 #endif
00221   typedef typename _Base::_Iterator_category  _Iterator_category;
00222 
00223 public:
00224   _DBG_iter() {}
00225     // boris : real type of iter would be nice
00226   _DBG_iter(const __owned_list* __c, const _Const_iterator& __it) :
00227     _DBG_iter_mid<_Container, _Traits>(__c, __it) {}
00228 
00229   // This allows conversions from iterator to const_iterator without being
00230   // redundant with the copy constructor below.
00231   _DBG_iter(const _Nonconst_mid& __rhs) :
00232     _DBG_iter_mid<_Container, _Traits>(__rhs) {}
00233 
00234   _DBG_iter(const  _Self& __rhs) :
00235     _DBG_iter_mid<_Container, _Traits>(__rhs) {}
00236 
00237   // This allows conversions from iterator to const_iterator without being
00238   // redundant with the copy assignment operator below.
00239   _Self& operator=(const _Nonconst_mid& __rhs) {
00240     (_Base&)*this = __rhs;
00241     return *this;
00242   }
00243 
00244   _Self& operator=(const  _Self& __rhs) {
00245     (_Base&)*this = __rhs;
00246     return *this;
00247   }
00248 
00249   reference operator*() const;
00250 
00251   _STLP_DEFINE_ARROW_OPERATOR
00252 
00253   _Self& operator++() {
00254     this->__increment();
00255     return *this;
00256   }
00257   _Self operator++(int) {
00258     _Self __tmp = *this;
00259     this->__increment();
00260     return __tmp;
00261   }
00262   _Self& operator--() {
00263     this->__decrement();
00264     return *this;
00265   }
00266   _Self operator--(int) {
00267     _Self __tmp = *this;
00268     this->__decrement();
00269     return __tmp;
00270   }
00271 
00272   _Self& operator+=(difference_type __n) {
00273     this->__advance(__n);
00274     return *this;
00275   }
00276 
00277   _Self& operator-=(difference_type __n) {
00278     this->__advance(-__n);
00279     return *this;
00280   }
00281   _Self operator+(difference_type __n) const {
00282     _Self __tmp(*this);
00283     __tmp.__advance(__n);
00284     return __tmp;
00285   }
00286   _Self operator-(difference_type __n) const {
00287     _Self __tmp(*this);
00288     __tmp.__advance(-__n);
00289     return __tmp;
00290   }
00291   reference operator[](difference_type __n) const { return *(*this + __n); }
00292 };
00293 
00294 template <class _Container, class _Traits>
00295 inline
00296 #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
00297 _STLP_TYPENAME_ON_RETURN_TYPE _Traits::reference
00298 #else
00299 _STLP_TYPENAME_ON_RETURN_TYPE _DBG_iter<_Container, _Traits>::reference
00300 #endif
00301 _DBG_iter<_Container, _Traits>::operator*() const {
00302   _STLP_DEBUG_CHECK(_Dereferenceable(*this))
00303   _STLP_DEBUG_CHECK(_Traits::_Check(*this))
00304   return *this->_M_iterator;
00305 }
00306 
00307 template <class _Container>
00308 inline bool
00309 operator==(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
00310   _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
00311   return __x._M_iterator == __y._M_iterator;
00312 }
00313 
00314 template <class _Container>
00315 inline bool
00316 operator<(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
00317   _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
00318   typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
00319   return _CompareIt(__x._M_iterator , __y._M_iterator, _Category());
00320 }
00321 
00322 template <class _Container>
00323 inline bool
00324 operator>(const _DBG_iter_base<_Container>& __x,
00325        const _DBG_iter_base<_Container>& __y) {
00326   typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
00327   return _CompareIt(__y._M_iterator , __x._M_iterator, _Category());
00328 }
00329 
00330 template <class _Container>
00331 inline bool
00332 operator>=(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
00333   _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
00334   typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
00335   return !_CompareIt(__x._M_iterator , __y._M_iterator, _Category());
00336 }
00337 
00338 template <class _Container>
00339 inline bool
00340 operator<=(const _DBG_iter_base<_Container>& __x,
00341        const _DBG_iter_base<_Container>& __y) {
00342   typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
00343   return !_CompareIt(__y._M_iterator , __x._M_iterator, _Category());
00344 }
00345 
00346 template <class _Container>
00347 inline bool
00348 operator!=(const _DBG_iter_base<_Container>& __x,
00349         const _DBG_iter_base<_Container>& __y) {
00350   _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
00351   return __x._M_iterator != __y._M_iterator;
00352 }
00353 
00354 //------------------------------------------
00355 
00356 template <class _Container, class _Traits>
00357 inline _DBG_iter<_Container, _Traits>
00358 operator+(ptrdiff_t __n, const _DBG_iter<_Container, _Traits>& __it) {
00359   _DBG_iter<_Container, _Traits> __tmp(__it);
00360   return __tmp += __n;
00361 }
00362 
00363 
00364 template <class _Iterator>
00365 inline _Iterator _Non_Dbg_iter(_Iterator __it)
00366 { return __it; }
00367 
00368 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
00369 template <class _Container, class _Traits>
00370 inline typename _DBG_iter<_Container, _Traits>::_Nonconst_iterator
00371 _Non_Dbg_iter(_DBG_iter<_Container, _Traits> __it)
00372 { return __it._M_iterator; }
00373 #endif
00374 
00375 /*
00376  * Helper classes to check iterator range or pointer validity
00377  * at construction time.
00378  */
00379 template <class _Container>
00380 class __construct_checker {
00381   typedef typename _Container::value_type value_type;
00382 protected:
00383   __construct_checker() {}
00384 
00385   __construct_checker(const value_type* __p) {
00386     _STLP_VERBOSE_ASSERT((__p != 0), _StlMsg_INVALID_ARGUMENT)
00387   }
00388 
00389 #if defined (_STLP_MEMBER_TEMPLATES)
00390   template <class _InputIter>
00391   __construct_checker(const _InputIter& __f, const _InputIter& __l) {
00392     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
00393     _M_check_dispatch(__f, __l, _Integral());
00394   }
00395 
00396   template <class _Integer>
00397   void _M_check_dispatch(_Integer , _Integer, const __true_type& /*IsIntegral*/) {}
00398 
00399   template <class _InputIter>
00400   void _M_check_dispatch(const _InputIter& __f, const _InputIter& __l, const __false_type& /*IsIntegral*/) {
00401     _STLP_DEBUG_CHECK(__check_range(__f,__l))
00402   }
00403 #endif
00404 
00405 #if !defined (_STLP_MEMBER_TEMPLATES) || !defined (_STLP_NO_METHOD_SPECIALIZATION)
00406   __construct_checker(const value_type* __f, const value_type* __l) {
00407     _STLP_DEBUG_CHECK(__check_ptr_range(__f,__l))
00408   }
00409 
00410   typedef _DBG_iter_base<_Container> _IteType;
00411   __construct_checker(const _IteType& __f, const _IteType& __l) {
00412     _STLP_DEBUG_CHECK(__check_range(__f,__l))
00413   }
00414 #endif
00415 };
00416 
00417 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
00418 #  if defined (_STLP_NESTED_TYPE_PARAM_BUG) ||\
00419      (defined (__SUNPRO_CC) && __SUNPRO_CC < 0x600) ||\
00420      (defined (_STLP_MSVC) && (_STLP_MSVC < 1100))
00421 #    define _STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS 1
00422 #  endif
00423 
00424 _STLP_MOVE_TO_STD_NAMESPACE
00425 
00426 template <class _Container>
00427 inline ptrdiff_t*
00428 distance_type(const _STLP_PRIV _DBG_iter_base<_Container>&) { return (ptrdiff_t*) 0; }
00429 
00430 #  if !defined (_STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS)
00431 template <class _Container>
00432 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::value_type*
00433 value_type(const _STLP_PRIV _DBG_iter_base<_Container>&) {
00434   typedef typename _STLP_PRIV _DBG_iter_base<_Container>::value_type _Val;
00435   return (_Val*)0;
00436 }
00437 
00438 template <class _Container>
00439 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category
00440 iterator_category(const _STLP_PRIV _DBG_iter_base<_Container>&) {
00441   typedef typename _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category _Category;
00442   return _Category();
00443 }
00444 #  endif
00445 
00446 _STLP_MOVE_TO_PRIV_NAMESPACE
00447 
00448 #endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
00449 
00450 _STLP_MOVE_TO_STD_NAMESPACE
00451 
00452 _STLP_END_NAMESPACE
00453 
00454 #endif /* INTERNAL_H */
00455 
00456 // Local Variables:
00457 // mode:C++
00458 // End:



Generated on Mon Mar 10 15:32:27 2008 by  doxygen 1.5.1