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 
36 template <class _Iterator>
_Decrement(_Iterator & __it,const bidirectional_iterator_tag &)37 void _Decrement(_Iterator& __it, const bidirectional_iterator_tag &)
38 { --__it; }
39 
40 template <class _Iterator>
_Decrement(_Iterator & __it,const random_access_iterator_tag &)41 void _Decrement(_Iterator& __it, const random_access_iterator_tag &)
42 { --__it; }
43 
44 template <class _Iterator>
_Decrement(_Iterator & __it,const forward_iterator_tag &)45 void _Decrement(_Iterator& __it, const forward_iterator_tag &)
46 { _STLP_ASSERT(0) }
47 
48 template <class _Iterator>
_Advance(_Iterator &,ptrdiff_t,const forward_iterator_tag &)49 void _Advance(_Iterator&, ptrdiff_t, const forward_iterator_tag &)
50 { _STLP_ASSERT(0) }
51 
52 template <class _Iterator>
_Advance(_Iterator & __it,ptrdiff_t,const bidirectional_iterator_tag &)53 void _Advance(_Iterator& __it, ptrdiff_t, const bidirectional_iterator_tag &)
54 { _STLP_ASSERT(0) }
55 
56 template <class _Iterator>
_Advance(_Iterator & __it,ptrdiff_t __n,const random_access_iterator_tag &)57 void _Advance(_Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &)
58 { __it += __n; }
59 
60 template <class _Iterator>
_DBG_distance(const _Iterator & __x,const _Iterator & __y,const random_access_iterator_tag &)61 ptrdiff_t _DBG_distance(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
62 { return __x - __y; }
63 
64 template <class _Iterator>
_DBG_distance(const _Iterator &,const _Iterator &,const forward_iterator_tag &)65 ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
66   _STLP_ASSERT(0)
67   return 0;
68 }
69 
70 template <class _Iterator>
_DBG_distance(const _Iterator &,const _Iterator &,const bidirectional_iterator_tag &)71 ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
72   _STLP_ASSERT(0)
73   return 0;
74 }
75 
76 template <class _Iterator>
_CompareIt(const _Iterator &,const _Iterator &,const forward_iterator_tag &)77 bool _CompareIt(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
78   _STLP_ASSERT(0)
79   return false;
80 }
81 
82 template <class _Iterator>
_CompareIt(const _Iterator &,const _Iterator &,const bidirectional_iterator_tag &)83 bool _CompareIt(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
84   _STLP_ASSERT(0)
85   return false;
86 }
87 
88 template <class _Iterator>
_CompareIt(const _Iterator & __x,const _Iterator & __y,const random_access_iterator_tag &)89 bool _CompareIt(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
90 { return __x < __y; }
91 
92 template <class _Iterator>
_Dereferenceable(const _Iterator & __it)93 bool _Dereferenceable(const _Iterator& __it)
94 { return (__it._Get_container_ptr() != 0) && !(__it._M_iterator == (__it._Get_container_ptr())->end()); }
95 
96 template <class _Iterator>
_Incrementable(const _Iterator & __it,ptrdiff_t __n,const forward_iterator_tag &)97 bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const forward_iterator_tag &)
98 { return (__n == 1) && _Dereferenceable(__it); }
99 
100 template <class _Iterator>
_Incrementable(const _Iterator & __it,ptrdiff_t __n,const bidirectional_iterator_tag &)101 bool _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 
108 template <class _Iterator>
_Incrementable(const _Iterator & __it,ptrdiff_t __n,const random_access_iterator_tag &)109 bool _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 
118 template <class _Container>
119 struct _DBG_iter_base : public __owned_link {
120 public:
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 
_DBG_iter_base_DBG_iter_base137   _DBG_iter_base() : __owned_link(0)  {}
_DBG_iter_base_DBG_iter_base138   _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
_Get_container_ptr_DBG_iter_base144   _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 
156 template <class _Container>
__increment()157 inline void _DBG_iter_base<_Container>::__increment() {
158   _STLP_DEBUG_CHECK(_Incrementable(*this, 1, _Iterator_category()))
159   ++_M_iterator;
160 }
161 
162 template <class _Container>
__decrement()163 inline void _DBG_iter_base<_Container>::__decrement() {
164   _STLP_DEBUG_CHECK(_Incrementable(*this, -1, _Iterator_category()))
165   _Decrement(_M_iterator, _Iterator_category());
166 }
167 
168 template <class _Container>
__advance(ptrdiff_t __n)169 inline 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 
174 template <class _Container>
175 ptrdiff_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 
182 template <class _Container, class _Traits>
183 struct _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 
_DBG_iter_mid_DBG_iter_mid188   _DBG_iter_mid() {}
189 
_DBG_iter_mid_DBG_iter_mid190   explicit _DBG_iter_mid(const _Nonconst_self& __it) :
191       _DBG_iter_base<_Container>(__it) {}
192 
_DBG_iter_mid_DBG_iter_mid193   _DBG_iter_mid(const __owned_list* __c, const _Const_iterator& __it) :
194       _DBG_iter_base<_Container>(__c, __it) {}
195 };
196 
197 template <class _Container, class _Traits>
198 struct _DBG_iter : public _DBG_iter_mid<_Container, _Traits> {
199   typedef _DBG_iter_base<_Container>          _Base;
200 public:
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 
209 private:
210   typedef _DBG_iter<_Container, _Traits>     _Self;
211   typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_mid;
212 
213 public:
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 
220 public:
_DBG_iter_DBG_iter221   _DBG_iter() {}
222     // boris : real type of iter would be nice
_DBG_iter_DBG_iter223   _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.
_DBG_iter_DBG_iter228   _DBG_iter(const _Nonconst_mid& __rhs) :
229     _DBG_iter_mid<_Container, _Traits>(__rhs) {}
230 
_DBG_iter_DBG_iter231   _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 
291 template <class _Container, class _Traits>
292 inline
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 
304 template <class _Container>
305 inline bool
306 operator==(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 
311 template <class _Container>
312 inline bool
313 operator<(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 
319 template <class _Container>
320 inline bool
321 operator>(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 
327 template <class _Container>
328 inline bool
329 operator>=(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 
335 template <class _Container>
336 inline bool
337 operator<=(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 
343 template <class _Container>
344 inline bool
345 operator!=(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 
353 template <class _Container, class _Traits>
354 inline _DBG_iter<_Container, _Traits>
355 operator+(ptrdiff_t __n, const _DBG_iter<_Container, _Traits>& __it) {
356   _DBG_iter<_Container, _Traits> __tmp(__it);
357   return __tmp += __n;
358 }
359 
360 
361 template <class _Iterator>
_Non_Dbg_iter(_Iterator __it)362 inline _Iterator _Non_Dbg_iter(_Iterator __it)
363 { return __it; }
364 
365 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
366 template <class _Container, class _Traits>
367 inline typename _DBG_iter<_Container, _Traits>::_Nonconst_iterator
_Non_Dbg_iter(const _DBG_iter<_Container,_Traits> & __it)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  */
376 template <class _Container>
377 class __construct_checker {
378   typedef typename _Container::value_type value_type;
379 protected:
__construct_checker()380   __construct_checker() {}
381 
__construct_checker(const value_type * __p)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>
__construct_checker(const _InputIter & __f,const _InputIter & __l)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>
_M_check_dispatch(_Integer,_Integer,const __true_type &)394   void _M_check_dispatch(_Integer , _Integer, const __true_type& /*IsIntegral*/) {}
395 
396   template <class _InputIter>
_M_check_dispatch(const _InputIter & __f,const _InputIter & __l,const __false_type &)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)
__construct_checker(const value_type * __f,const value_type * __l)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;
__construct_checker(const _IteType & __f,const _IteType & __l)408   __construct_checker(const _IteType& __f, const _IteType& __l) {
409     _STLP_DEBUG_CHECK(__check_range(__f,__l))
410   }
411 #endif
412 #if defined (__BORLANDC__)
~__construct_checker()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 
425 template <class _Container>
426 inline ptrdiff_t*
distance_type(const _STLP_PRIV _DBG_iter_base<_Container> &)427 distance_type(const _STLP_PRIV _DBG_iter_base<_Container>&) { return (ptrdiff_t*) 0; }
428 
429 #  if !defined (_STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS)
430 template <class _Container>
431 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::value_type*
value_type(const _STLP_PRIV _DBG_iter_base<_Container> &)432 value_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 
437 template <class _Container>
438 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category
iterator_category(const _STLP_PRIV _DBG_iter_base<_Container> &)439 iterator_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