1/* 2 * 3 * Copyright (c) 1997 4 * Moscow Center for SPARC Technology 5 * 6 * Copyright (c) 1999 7 * Boris Fomitchev 8 * 9 * This material is provided "as is", with absolutely no warranty expressed 10 * or implied. Any use is at your own risk. 11 * 12 * Permission to use or copy this software for any purpose is hereby granted 13 * without fee, provided the above notices are retained on all copies. 14 * Permission to modify the code and to distribute modified code is granted, 15 * provided the above notices are retained, and a notice that the code was 16 * modified is included with the above copyright notice. 17 * 18 */ 19 20#ifndef _STLP_DBG_ITERATOR_H 21#define _STLP_DBG_ITERATOR_H 22 23#ifndef _STLP_INTERNAL_PAIR_H 24# include <stl/_pair.h> 25#endif 26 27#ifndef _STLP_INTERNAL_ALLOC_H 28# include <stl/_alloc.h> 29#endif 30 31_STLP_BEGIN_NAMESPACE 32_STLP_MOVE_TO_PRIV_NAMESPACE 33 34//============================================================ 35 36template <class _Iterator> 37void _Decrement(_Iterator& __it, const bidirectional_iterator_tag &) 38{ --__it; } 39 40template <class _Iterator> 41void _Decrement(_Iterator& __it, const random_access_iterator_tag &) 42{ --__it; } 43 44template <class _Iterator> 45void _Decrement(_Iterator& __it, const forward_iterator_tag &) 46{ _STLP_ASSERT(0) } 47 48template <class _Iterator> 49void _Advance(_Iterator&, ptrdiff_t, const forward_iterator_tag &) 50{ _STLP_ASSERT(0) } 51 52template <class _Iterator> 53void _Advance(_Iterator& __it, ptrdiff_t, const bidirectional_iterator_tag &) 54{ _STLP_ASSERT(0) } 55 56template <class _Iterator> 57void _Advance(_Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &) 58{ __it += __n; } 59 60template <class _Iterator> 61ptrdiff_t _DBG_distance(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &) 62{ return __x - __y; } 63 64template <class _Iterator> 65ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const forward_iterator_tag &) { 66 _STLP_ASSERT(0) 67 return 0; 68} 69 70template <class _Iterator> 71ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) { 72 _STLP_ASSERT(0) 73 return 0; 74} 75 76template <class _Iterator> 77bool _CompareIt(const _Iterator&, const _Iterator&, const forward_iterator_tag &) { 78 _STLP_ASSERT(0) 79 return false; 80} 81 82template <class _Iterator> 83bool _CompareIt(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) { 84 _STLP_ASSERT(0) 85 return false; 86} 87 88template <class _Iterator> 89bool _CompareIt(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &) 90{ return __x < __y; } 91 92template <class _Iterator> 93bool _Dereferenceable(const _Iterator& __it) 94{ return (__it._Get_container_ptr() != 0) && !(__it._M_iterator == (__it._Get_container_ptr())->end()); } 95 96template <class _Iterator> 97bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const forward_iterator_tag &) 98{ return (__n == 1) && _Dereferenceable(__it); } 99 100template <class _Iterator> 101bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const bidirectional_iterator_tag &) { 102 typedef typename _Iterator::_Container_type __container_type; 103 __container_type* __c = __it._Get_container_ptr(); 104 return (__c != 0) && ((__n == 1 && __it._M_iterator != __c->end() ) || 105 (__n == -1 && __it._M_iterator != __c->begin())); 106} 107 108template <class _Iterator> 109bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &) { 110 typedef typename _Iterator::_Container_type __container_type; 111 __container_type* __c = __it._Get_container_ptr(); 112 if (__c == 0) return false; 113 ptrdiff_t __new_pos = (__it._M_iterator - __c->begin()) + __n; 114 return (__new_pos >= 0) && (__STATIC_CAST(typename __container_type::size_type, __new_pos) <= __c->size()); 115} 116 117 118template <class _Container> 119struct _DBG_iter_base : public __owned_link { 120public: 121 typedef typename _Container::value_type value_type; 122 typedef typename _Container::reference reference; 123 typedef typename _Container::pointer pointer; 124 typedef ptrdiff_t difference_type; 125 //private: 126 typedef typename _Container::iterator _Nonconst_iterator; 127 typedef typename _Container::const_iterator _Const_iterator; 128 typedef _Container _Container_type; 129 130#ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION 131 typedef typename iterator_traits<_Const_iterator>::iterator_category _Iterator_category; 132#else 133 typedef typename _Container::_Iterator_category _Iterator_category; 134#endif 135 typedef _Iterator_category iterator_category; 136 137 _DBG_iter_base() : __owned_link(0) {} 138 _DBG_iter_base(const __owned_list* __c, const _Const_iterator& __it) : 139#if defined(__HP_aCC) && (__HP_aCC < 60000) 140 __owned_link(__c), _M_iterator(*__REINTERPRET_CAST(const _Nonconst_iterator *, &__it)) {} 141#else 142 __owned_link(__c), _M_iterator(*(const _Nonconst_iterator*)&__it) {} 143#endif 144 _Container* _Get_container_ptr() const { 145 return (_Container*)__stl_debugger::_Get_container_ptr(this); 146 } 147 148 void __increment(); 149 void __decrement(); 150 void __advance(ptrdiff_t __n); 151 152// protected: 153 _Nonconst_iterator _M_iterator; 154}; 155 156template <class _Container> 157inline void _DBG_iter_base<_Container>::__increment() { 158 _STLP_DEBUG_CHECK(_Incrementable(*this, 1, _Iterator_category())) 159 ++_M_iterator; 160} 161 162template <class _Container> 163inline void _DBG_iter_base<_Container>::__decrement() { 164 _STLP_DEBUG_CHECK(_Incrementable(*this, -1, _Iterator_category())) 165 _Decrement(_M_iterator, _Iterator_category()); 166} 167 168template <class _Container> 169inline void _DBG_iter_base<_Container>::__advance(ptrdiff_t __n) { 170 _STLP_DEBUG_CHECK(_Incrementable(*this, __n, _Iterator_category())) 171 _Advance(_M_iterator, __n, _Iterator_category()); 172} 173 174template <class _Container> 175ptrdiff_t operator-(const _DBG_iter_base<_Container>& __x, 176 const _DBG_iter_base<_Container>& __y ) { 177 typedef typename _DBG_iter_base<_Container>::_Iterator_category _Iterator_category; 178 _STLP_DEBUG_CHECK(__check_same_owner(__x, __y)) 179 return _DBG_distance(__x._M_iterator,__y._M_iterator, _Iterator_category()); 180} 181 182template <class _Container, class _Traits> 183struct _DBG_iter_mid : public _DBG_iter_base<_Container> { 184 typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_self; 185 typedef typename _Container::iterator _Nonconst_iterator; 186 typedef typename _Container::const_iterator _Const_iterator; 187 188 _DBG_iter_mid() {} 189 190 explicit _DBG_iter_mid(const _Nonconst_self& __it) : 191 _DBG_iter_base<_Container>(__it) {} 192 193 _DBG_iter_mid(const __owned_list* __c, const _Const_iterator& __it) : 194 _DBG_iter_base<_Container>(__c, __it) {} 195}; 196 197template <class _Container, class _Traits> 198struct _DBG_iter : public _DBG_iter_mid<_Container, _Traits> { 199 typedef _DBG_iter_base<_Container> _Base; 200public: 201 typedef typename _Base::value_type value_type; 202 typedef typename _Base::difference_type difference_type; 203 typedef typename _Traits::reference reference; 204 typedef typename _Traits::pointer pointer; 205 206 typedef typename _Base::_Nonconst_iterator _Nonconst_iterator; 207 typedef typename _Base::_Const_iterator _Const_iterator; 208 209private: 210 typedef _DBG_iter<_Container, _Traits> _Self; 211 typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_mid; 212 213public: 214 215#ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION 216 typedef typename _Base::iterator_category iterator_category; 217#endif 218 typedef typename _Base::_Iterator_category _Iterator_category; 219 220public: 221 _DBG_iter() {} 222 // boris : real type of iter would be nice 223 _DBG_iter(const __owned_list* __c, const _Const_iterator& __it) : 224 _DBG_iter_mid<_Container, _Traits>(__c, __it) {} 225 226 // This allows conversions from iterator to const_iterator without being 227 // redundant with the copy constructor below. 228 _DBG_iter(const _Nonconst_mid& __rhs) : 229 _DBG_iter_mid<_Container, _Traits>(__rhs) {} 230 231 _DBG_iter(const _Self& __rhs) : 232 _DBG_iter_mid<_Container, _Traits>(__rhs) {} 233 234 // This allows conversions from iterator to const_iterator without being 235 // redundant with the copy assignment operator below. 236 _Self& operator=(const _Nonconst_mid& __rhs) { 237 (_Base&)*this = __rhs; 238 return *this; 239 } 240 241 _Self& operator=(const _Self& __rhs) { 242 (_Base&)*this = __rhs; 243 return *this; 244 } 245 246 reference operator*() const; 247 248 _STLP_DEFINE_ARROW_OPERATOR 249 250 _Self& operator++() { 251 this->__increment(); 252 return *this; 253 } 254 _Self operator++(int) { 255 _Self __tmp = *this; 256 this->__increment(); 257 return __tmp; 258 } 259 _Self& operator--() { 260 this->__decrement(); 261 return *this; 262 } 263 _Self operator--(int) { 264 _Self __tmp = *this; 265 this->__decrement(); 266 return __tmp; 267 } 268 269 _Self& operator+=(difference_type __n) { 270 this->__advance(__n); 271 return *this; 272 } 273 274 _Self& operator-=(difference_type __n) { 275 this->__advance(-__n); 276 return *this; 277 } 278 _Self operator+(difference_type __n) const { 279 _Self __tmp(*this); 280 __tmp.__advance(__n); 281 return __tmp; 282 } 283 _Self operator-(difference_type __n) const { 284 _Self __tmp(*this); 285 __tmp.__advance(-__n); 286 return __tmp; 287 } 288 reference operator[](difference_type __n) const { return *(*this + __n); } 289}; 290 291template <class _Container, class _Traits> 292inline 293#if defined (_STLP_NESTED_TYPE_PARAM_BUG) 294_STLP_TYPENAME_ON_RETURN_TYPE _Traits::reference 295#else 296_STLP_TYPENAME_ON_RETURN_TYPE _DBG_iter<_Container, _Traits>::reference 297#endif 298_DBG_iter<_Container, _Traits>::operator*() const { 299 _STLP_DEBUG_CHECK(_Dereferenceable(*this)) 300 _STLP_DEBUG_CHECK(_Traits::_Check(*this)) 301 return *this->_M_iterator; 302} 303 304template <class _Container> 305inline bool 306operator==(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) { 307 _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y)) 308 return __x._M_iterator == __y._M_iterator; 309} 310 311template <class _Container> 312inline bool 313operator<(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) { 314 _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y)) 315 typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category; 316 return _CompareIt(__x._M_iterator , __y._M_iterator, _Category()); 317} 318 319template <class _Container> 320inline bool 321operator>(const _DBG_iter_base<_Container>& __x, 322 const _DBG_iter_base<_Container>& __y) { 323 typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category; 324 return _CompareIt(__y._M_iterator , __x._M_iterator, _Category()); 325} 326 327template <class _Container> 328inline bool 329operator>=(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) { 330 _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y)) 331 typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category; 332 return !_CompareIt(__x._M_iterator , __y._M_iterator, _Category()); 333} 334 335template <class _Container> 336inline bool 337operator<=(const _DBG_iter_base<_Container>& __x, 338 const _DBG_iter_base<_Container>& __y) { 339 typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category; 340 return !_CompareIt(__y._M_iterator , __x._M_iterator, _Category()); 341} 342 343template <class _Container> 344inline bool 345operator!=(const _DBG_iter_base<_Container>& __x, 346 const _DBG_iter_base<_Container>& __y) { 347 _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y)) 348 return __x._M_iterator != __y._M_iterator; 349} 350 351//------------------------------------------ 352 353template <class _Container, class _Traits> 354inline _DBG_iter<_Container, _Traits> 355operator+(ptrdiff_t __n, const _DBG_iter<_Container, _Traits>& __it) { 356 _DBG_iter<_Container, _Traits> __tmp(__it); 357 return __tmp += __n; 358} 359 360 361template <class _Iterator> 362inline _Iterator _Non_Dbg_iter(_Iterator __it) 363{ return __it; } 364 365#if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 366template <class _Container, class _Traits> 367inline typename _DBG_iter<_Container, _Traits>::_Nonconst_iterator 368_Non_Dbg_iter(const _DBG_iter<_Container, _Traits>& __it) 369{ return __it._M_iterator; } 370#endif 371 372/* 373 * Helper classes to check iterator range or pointer validity 374 * at construction time. 375 */ 376template <class _Container> 377class __construct_checker { 378 typedef typename _Container::value_type value_type; 379protected: 380 __construct_checker() {} 381 382 __construct_checker(const value_type* __p) { 383 _STLP_VERBOSE_ASSERT((__p != 0), _StlMsg_INVALID_ARGUMENT) 384 } 385 386#if defined (_STLP_MEMBER_TEMPLATES) 387 template <class _InputIter> 388 __construct_checker(const _InputIter& __f, const _InputIter& __l) { 389 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 390 _M_check_dispatch(__f, __l, _Integral()); 391 } 392 393 template <class _Integer> 394 void _M_check_dispatch(_Integer , _Integer, const __true_type& /*IsIntegral*/) {} 395 396 template <class _InputIter> 397 void _M_check_dispatch(const _InputIter& __f, const _InputIter& __l, const __false_type& /*IsIntegral*/) { 398 _STLP_DEBUG_CHECK(__check_range(__f,__l)) 399 } 400#endif 401 402#if !defined (_STLP_MEMBER_TEMPLATES) || !defined (_STLP_NO_METHOD_SPECIALIZATION) 403 __construct_checker(const value_type* __f, const value_type* __l) { 404 _STLP_DEBUG_CHECK(__check_ptr_range(__f,__l)) 405 } 406 407 typedef _DBG_iter_base<_Container> _IteType; 408 __construct_checker(const _IteType& __f, const _IteType& __l) { 409 _STLP_DEBUG_CHECK(__check_range(__f,__l)) 410 } 411#endif 412#if defined (__BORLANDC__) 413 ~__construct_checker(){} 414#endif 415}; 416 417#if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES) 418# if defined (_STLP_NESTED_TYPE_PARAM_BUG) ||\ 419 (defined (__SUNPRO_CC) && __SUNPRO_CC < 0x600) 420# define _STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS 1 421# endif 422 423_STLP_MOVE_TO_STD_NAMESPACE 424 425template <class _Container> 426inline ptrdiff_t* 427distance_type(const _STLP_PRIV _DBG_iter_base<_Container>&) { return (ptrdiff_t*) 0; } 428 429# if !defined (_STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS) 430template <class _Container> 431inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::value_type* 432value_type(const _STLP_PRIV _DBG_iter_base<_Container>&) { 433 typedef _STLP_TYPENAME _STLP_PRIV _DBG_iter_base<_Container>::value_type _Val; 434 return (_Val*)0; 435} 436 437template <class _Container> 438inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category 439iterator_category(const _STLP_PRIV _DBG_iter_base<_Container>&) { 440 typedef _STLP_TYPENAME _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category _Category; 441 return _Category(); 442} 443# endif 444 445_STLP_MOVE_TO_PRIV_NAMESPACE 446 447#endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */ 448 449_STLP_MOVE_TO_STD_NAMESPACE 450 451_STLP_END_NAMESPACE 452 453#endif /* INTERNAL_H */ 454 455// Local Variables: 456// mode:C++ 457// End: 458