_iterator.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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. #ifndef _STLP_DBG_ITERATOR_H
  20. #define _STLP_DBG_ITERATOR_H
  21. #ifndef _STLP_INTERNAL_PAIR_H
  22. # include <stl/_pair.h>
  23. #endif
  24. #ifndef _STLP_INTERNAL_ALLOC_H
  25. # include <stl/_alloc.h>
  26. #endif
  27. _STLP_BEGIN_NAMESPACE
  28. _STLP_MOVE_TO_PRIV_NAMESPACE
  29. //============================================================
  30. template <class _Iterator>
  31. void _Decrement(_Iterator& __it, const bidirectional_iterator_tag &)
  32. { --__it; }
  33. template <class _Iterator>
  34. void _Decrement(_Iterator& __it, const random_access_iterator_tag &)
  35. { --__it; }
  36. template <class _Iterator>
  37. void _Decrement(_Iterator& __it, const forward_iterator_tag &)
  38. { _STLP_ASSERT(0) }
  39. template <class _Iterator>
  40. void _Advance(_Iterator&, ptrdiff_t, const forward_iterator_tag &)
  41. { _STLP_ASSERT(0) }
  42. template <class _Iterator>
  43. void _Advance(_Iterator& __it, ptrdiff_t, const bidirectional_iterator_tag &)
  44. { _STLP_ASSERT(0) }
  45. template <class _Iterator>
  46. void _Advance(_Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &)
  47. { __it += __n; }
  48. template <class _Iterator>
  49. ptrdiff_t _DBG_distance(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
  50. { return __x - __y; }
  51. template <class _Iterator>
  52. ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
  53. _STLP_ASSERT(0)
  54. return 0;
  55. }
  56. template <class _Iterator>
  57. ptrdiff_t _DBG_distance(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
  58. _STLP_ASSERT(0)
  59. return 0;
  60. }
  61. template <class _Iterator>
  62. bool _CompareIt(const _Iterator&, const _Iterator&, const forward_iterator_tag &) {
  63. _STLP_ASSERT(0)
  64. return false;
  65. }
  66. template <class _Iterator>
  67. bool _CompareIt(const _Iterator&, const _Iterator&, const bidirectional_iterator_tag &) {
  68. _STLP_ASSERT(0)
  69. return false;
  70. }
  71. template <class _Iterator>
  72. bool _CompareIt(const _Iterator& __x, const _Iterator& __y, const random_access_iterator_tag &)
  73. { return __x < __y; }
  74. template <class _Iterator>
  75. bool _Dereferenceable(const _Iterator& __it)
  76. { return (__it._Get_container_ptr() != 0) && !(__it._M_iterator == (__it._Get_container_ptr())->end()); }
  77. template <class _Iterator>
  78. bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const forward_iterator_tag &)
  79. { return (__n == 1) && _Dereferenceable(__it); }
  80. template <class _Iterator>
  81. bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const bidirectional_iterator_tag &) {
  82. typedef typename _Iterator::_Container_type __container_type;
  83. __container_type* __c = __it._Get_container_ptr();
  84. return (__c != 0) && ((__n == 1 && __it._M_iterator != __c->end() ) ||
  85. (__n == -1 && __it._M_iterator != __c->begin()));
  86. }
  87. template <class _Iterator>
  88. bool _Incrementable(const _Iterator& __it, ptrdiff_t __n, const random_access_iterator_tag &) {
  89. typedef typename _Iterator::_Container_type __container_type;
  90. __container_type* __c = __it._Get_container_ptr();
  91. if (__c == 0) return false;
  92. ptrdiff_t __new_pos = (__it._M_iterator - __c->begin()) + __n;
  93. return (__new_pos >= 0) && (__STATIC_CAST(typename __container_type::size_type, __new_pos) <= __c->size());
  94. }
  95. template <class _Container>
  96. struct _DBG_iter_base : public __owned_link {
  97. public:
  98. typedef typename _Container::value_type value_type;
  99. typedef typename _Container::reference reference;
  100. typedef typename _Container::pointer pointer;
  101. typedef ptrdiff_t difference_type;
  102. //private:
  103. typedef typename _Container::iterator _Nonconst_iterator;
  104. typedef typename _Container::const_iterator _Const_iterator;
  105. typedef _Container _Container_type;
  106. #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
  107. typedef typename iterator_traits<_Const_iterator>::iterator_category _Iterator_category;
  108. #else
  109. typedef typename _Container::_Iterator_category _Iterator_category;
  110. #endif
  111. typedef _Iterator_category iterator_category;
  112. _DBG_iter_base() : __owned_link(0) {}
  113. _DBG_iter_base(const __owned_list* __c, const _Const_iterator& __it) :
  114. #if defined(__HP_aCC) && (__HP_aCC < 60000)
  115. __owned_link(__c), _M_iterator(*__REINTERPRET_CAST(const _Nonconst_iterator *, &__it)) {}
  116. #else
  117. __owned_link(__c), _M_iterator(*(const _Nonconst_iterator*)&__it) {}
  118. #endif
  119. _Container* _Get_container_ptr() const {
  120. return (_Container*)__stl_debugger::_Get_container_ptr(this);
  121. }
  122. void __increment();
  123. void __decrement();
  124. void __advance(ptrdiff_t __n);
  125. // protected:
  126. _Nonconst_iterator _M_iterator;
  127. };
  128. template <class _Container>
  129. inline void _DBG_iter_base<_Container>::__increment() {
  130. _STLP_DEBUG_CHECK(_Incrementable(*this, 1, _Iterator_category()))
  131. ++_M_iterator;
  132. }
  133. template <class _Container>
  134. inline void _DBG_iter_base<_Container>::__decrement() {
  135. _STLP_DEBUG_CHECK(_Incrementable(*this, -1, _Iterator_category()))
  136. _Decrement(_M_iterator, _Iterator_category());
  137. }
  138. template <class _Container>
  139. inline void _DBG_iter_base<_Container>::__advance(ptrdiff_t __n) {
  140. _STLP_DEBUG_CHECK(_Incrementable(*this, __n, _Iterator_category()))
  141. _Advance(_M_iterator, __n, _Iterator_category());
  142. }
  143. template <class _Container>
  144. ptrdiff_t operator-(const _DBG_iter_base<_Container>& __x,
  145. const _DBG_iter_base<_Container>& __y ) {
  146. typedef typename _DBG_iter_base<_Container>::_Iterator_category _Iterator_category;
  147. _STLP_DEBUG_CHECK(__check_same_owner(__x, __y))
  148. return _DBG_distance(__x._M_iterator,__y._M_iterator, _Iterator_category());
  149. }
  150. template <class _Container, class _Traits>
  151. struct _DBG_iter_mid : public _DBG_iter_base<_Container> {
  152. typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_self;
  153. typedef typename _Container::iterator _Nonconst_iterator;
  154. typedef typename _Container::const_iterator _Const_iterator;
  155. _DBG_iter_mid() {}
  156. explicit _DBG_iter_mid(const _Nonconst_self& __it) :
  157. _DBG_iter_base<_Container>(__it) {}
  158. _DBG_iter_mid(const __owned_list* __c, const _Const_iterator& __it) :
  159. _DBG_iter_base<_Container>(__c, __it) {}
  160. };
  161. template <class _Container, class _Traits>
  162. struct _DBG_iter : public _DBG_iter_mid<_Container, _Traits> {
  163. typedef _DBG_iter_base<_Container> _Base;
  164. public:
  165. typedef typename _Base::value_type value_type;
  166. typedef typename _Base::difference_type difference_type;
  167. typedef typename _Traits::reference reference;
  168. typedef typename _Traits::pointer pointer;
  169. typedef typename _Base::_Nonconst_iterator _Nonconst_iterator;
  170. typedef typename _Base::_Const_iterator _Const_iterator;
  171. private:
  172. typedef _DBG_iter<_Container, _Traits> _Self;
  173. typedef _DBG_iter_mid<_Container, typename _Traits::_NonConstTraits> _Nonconst_mid;
  174. public:
  175. #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
  176. typedef typename _Base::iterator_category iterator_category;
  177. #endif
  178. typedef typename _Base::_Iterator_category _Iterator_category;
  179. public:
  180. _DBG_iter() {}
  181. // boris : real type of iter would be nice
  182. _DBG_iter(const __owned_list* __c, const _Const_iterator& __it) :
  183. _DBG_iter_mid<_Container, _Traits>(__c, __it) {}
  184. // This allows conversions from iterator to const_iterator without being
  185. // redundant with the copy constructor below.
  186. _DBG_iter(const _Nonconst_mid& __rhs) :
  187. _DBG_iter_mid<_Container, _Traits>(__rhs) {}
  188. _DBG_iter(const _Self& __rhs) :
  189. _DBG_iter_mid<_Container, _Traits>(__rhs) {}
  190. // This allows conversions from iterator to const_iterator without being
  191. // redundant with the copy assignment operator below.
  192. _Self& operator=(const _Nonconst_mid& __rhs) {
  193. (_Base&)*this = __rhs;
  194. return *this;
  195. }
  196. _Self& operator=(const _Self& __rhs) {
  197. (_Base&)*this = __rhs;
  198. return *this;
  199. }
  200. reference operator*() const;
  201. _STLP_DEFINE_ARROW_OPERATOR
  202. _Self& operator++() {
  203. this->__increment();
  204. return *this;
  205. }
  206. _Self operator++(int) {
  207. _Self __tmp = *this;
  208. this->__increment();
  209. return __tmp;
  210. }
  211. _Self& operator--() {
  212. this->__decrement();
  213. return *this;
  214. }
  215. _Self operator--(int) {
  216. _Self __tmp = *this;
  217. this->__decrement();
  218. return __tmp;
  219. }
  220. _Self& operator+=(difference_type __n) {
  221. this->__advance(__n);
  222. return *this;
  223. }
  224. _Self& operator-=(difference_type __n) {
  225. this->__advance(-__n);
  226. return *this;
  227. }
  228. _Self operator+(difference_type __n) const {
  229. _Self __tmp(*this);
  230. __tmp.__advance(__n);
  231. return __tmp;
  232. }
  233. _Self operator-(difference_type __n) const {
  234. _Self __tmp(*this);
  235. __tmp.__advance(-__n);
  236. return __tmp;
  237. }
  238. reference operator[](difference_type __n) const { return *(*this + __n); }
  239. };
  240. template <class _Container, class _Traits>
  241. inline
  242. #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
  243. _STLP_TYPENAME_ON_RETURN_TYPE _Traits::reference
  244. #else
  245. _STLP_TYPENAME_ON_RETURN_TYPE _DBG_iter<_Container, _Traits>::reference
  246. #endif
  247. _DBG_iter<_Container, _Traits>::operator*() const {
  248. _STLP_DEBUG_CHECK(_Dereferenceable(*this))
  249. _STLP_DEBUG_CHECK(_Traits::_Check(*this))
  250. return *this->_M_iterator;
  251. }
  252. template <class _Container>
  253. inline bool
  254. operator==(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
  255. _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
  256. return __x._M_iterator == __y._M_iterator;
  257. }
  258. template <class _Container>
  259. inline bool
  260. operator<(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
  261. _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
  262. typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
  263. return _CompareIt(__x._M_iterator , __y._M_iterator, _Category());
  264. }
  265. template <class _Container>
  266. inline bool
  267. operator>(const _DBG_iter_base<_Container>& __x,
  268. const _DBG_iter_base<_Container>& __y) {
  269. typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
  270. return _CompareIt(__y._M_iterator , __x._M_iterator, _Category());
  271. }
  272. template <class _Container>
  273. inline bool
  274. operator>=(const _DBG_iter_base<_Container>& __x, const _DBG_iter_base<_Container>& __y) {
  275. _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
  276. typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
  277. return !_CompareIt(__x._M_iterator , __y._M_iterator, _Category());
  278. }
  279. template <class _Container>
  280. inline bool
  281. operator<=(const _DBG_iter_base<_Container>& __x,
  282. const _DBG_iter_base<_Container>& __y) {
  283. typedef typename _DBG_iter_base<_Container>::_Iterator_category _Category;
  284. return !_CompareIt(__y._M_iterator , __x._M_iterator, _Category());
  285. }
  286. template <class _Container>
  287. inline bool
  288. operator!=(const _DBG_iter_base<_Container>& __x,
  289. const _DBG_iter_base<_Container>& __y) {
  290. _STLP_DEBUG_CHECK(__check_same_or_null_owner(__x, __y))
  291. return __x._M_iterator != __y._M_iterator;
  292. }
  293. //------------------------------------------
  294. template <class _Container, class _Traits>
  295. inline _DBG_iter<_Container, _Traits>
  296. operator+(ptrdiff_t __n, const _DBG_iter<_Container, _Traits>& __it) {
  297. _DBG_iter<_Container, _Traits> __tmp(__it);
  298. return __tmp += __n;
  299. }
  300. template <class _Iterator>
  301. inline _Iterator _Non_Dbg_iter(_Iterator __it)
  302. { return __it; }
  303. #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
  304. template <class _Container, class _Traits>
  305. inline typename _DBG_iter<_Container, _Traits>::_Nonconst_iterator
  306. _Non_Dbg_iter(const _DBG_iter<_Container, _Traits>& __it)
  307. { return __it._M_iterator; }
  308. #endif
  309. /*
  310. * Helper classes to check iterator range or pointer validity
  311. * at construction time.
  312. */
  313. template <class _Container>
  314. class __construct_checker {
  315. typedef typename _Container::value_type value_type;
  316. protected:
  317. __construct_checker() {}
  318. __construct_checker(const value_type* __p) {
  319. _STLP_VERBOSE_ASSERT((__p != 0), _StlMsg_INVALID_ARGUMENT)
  320. }
  321. #if defined (_STLP_MEMBER_TEMPLATES)
  322. template <class _InputIter>
  323. __construct_checker(const _InputIter& __f, const _InputIter& __l) {
  324. typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
  325. _M_check_dispatch(__f, __l, _Integral());
  326. }
  327. template <class _Integer>
  328. void _M_check_dispatch(_Integer , _Integer, const __true_type& /*IsIntegral*/) {}
  329. template <class _InputIter>
  330. void _M_check_dispatch(const _InputIter& __f, const _InputIter& __l, const __false_type& /*IsIntegral*/) {
  331. _STLP_DEBUG_CHECK(__check_range(__f,__l))
  332. }
  333. #endif
  334. #if !defined (_STLP_MEMBER_TEMPLATES) || !defined (_STLP_NO_METHOD_SPECIALIZATION)
  335. __construct_checker(const value_type* __f, const value_type* __l) {
  336. _STLP_DEBUG_CHECK(__check_ptr_range(__f,__l))
  337. }
  338. typedef _DBG_iter_base<_Container> _IteType;
  339. __construct_checker(const _IteType& __f, const _IteType& __l) {
  340. _STLP_DEBUG_CHECK(__check_range(__f,__l))
  341. }
  342. #endif
  343. #if defined (__BORLANDC__)
  344. ~__construct_checker(){}
  345. #endif
  346. };
  347. #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
  348. # if defined (_STLP_NESTED_TYPE_PARAM_BUG) ||\
  349. (defined (__SUNPRO_CC) && __SUNPRO_CC < 0x600)
  350. # define _STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS 1
  351. # endif
  352. _STLP_MOVE_TO_STD_NAMESPACE
  353. template <class _Container>
  354. inline ptrdiff_t*
  355. distance_type(const _STLP_PRIV _DBG_iter_base<_Container>&) { return (ptrdiff_t*) 0; }
  356. # if !defined (_STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS)
  357. template <class _Container>
  358. inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::value_type*
  359. value_type(const _STLP_PRIV _DBG_iter_base<_Container>&) {
  360. typedef _STLP_TYPENAME _STLP_PRIV _DBG_iter_base<_Container>::value_type _Val;
  361. return (_Val*)0;
  362. }
  363. template <class _Container>
  364. inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category
  365. iterator_category(const _STLP_PRIV _DBG_iter_base<_Container>&) {
  366. typedef _STLP_TYPENAME _STLP_PRIV _DBG_iter_base<_Container>::_Iterator_category _Category;
  367. return _Category();
  368. }
  369. # endif
  370. _STLP_MOVE_TO_PRIV_NAMESPACE
  371. #endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
  372. _STLP_MOVE_TO_STD_NAMESPACE
  373. _STLP_END_NAMESPACE
  374. #endif /* INTERNAL_H */
  375. // Local Variables:
  376. // mode:C++
  377. // End: