iterator_tracker.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // Profiling iterator implementation -*- C++ -*-
  2. // Copyright (C) 2009-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file profile/iterator_tracker.h
  21. * This file is a GNU profile extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER
  24. #define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1
  25. #include <ext/type_traits.h>
  26. namespace std _GLIBCXX_VISIBILITY(default)
  27. {
  28. namespace __profile
  29. {
  30. template<typename _Iterator, typename _Sequence>
  31. class __iterator_tracker
  32. {
  33. typedef __iterator_tracker _Self;
  34. // The underlying iterator
  35. _Iterator _M_current;
  36. // The underlying data structure
  37. const _Sequence* _M_ds;
  38. typedef std::iterator_traits<_Iterator> _Traits;
  39. public:
  40. typedef _Iterator _Base_iterator;
  41. typedef typename _Traits::iterator_category iterator_category;
  42. typedef typename _Traits::value_type value_type;
  43. typedef typename _Traits::difference_type difference_type;
  44. typedef typename _Traits::reference reference;
  45. typedef typename _Traits::pointer pointer;
  46. __iterator_tracker() _GLIBCXX_NOEXCEPT
  47. : _M_current(), _M_ds(0) { }
  48. __iterator_tracker(const _Iterator& __i, const _Sequence* __seq)
  49. _GLIBCXX_NOEXCEPT
  50. : _M_current(__i), _M_ds(__seq) { }
  51. __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT
  52. : _M_current(__x._M_current), _M_ds(__x._M_ds) { }
  53. template<typename _MutableIterator>
  54. __iterator_tracker(const __iterator_tracker<_MutableIterator,
  55. typename __gnu_cxx::__enable_if
  56. <(std::__are_same<_MutableIterator, typename
  57. _Sequence::iterator::_Base_iterator>::__value),
  58. _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
  59. : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
  60. _Iterator
  61. base() const _GLIBCXX_NOEXCEPT { return _M_current; }
  62. /**
  63. * @brief Conversion to underlying non-debug iterator to allow
  64. * better interaction with non-profile containers.
  65. */
  66. operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; }
  67. pointer
  68. operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; }
  69. __iterator_tracker&
  70. operator++() _GLIBCXX_NOEXCEPT
  71. {
  72. _M_ds->_M_profile_iterate();
  73. ++_M_current;
  74. return *this;
  75. }
  76. __iterator_tracker
  77. operator++(int) _GLIBCXX_NOEXCEPT
  78. {
  79. _M_ds->_M_profile_iterate();
  80. __iterator_tracker __tmp(*this);
  81. ++_M_current;
  82. return __tmp;
  83. }
  84. __iterator_tracker&
  85. operator--() _GLIBCXX_NOEXCEPT
  86. {
  87. _M_ds->_M_profile_iterate(1);
  88. --_M_current;
  89. return *this;
  90. }
  91. __iterator_tracker
  92. operator--(int) _GLIBCXX_NOEXCEPT
  93. {
  94. _M_ds->_M_profile_iterate(1);
  95. __iterator_tracker __tmp(*this);
  96. --_M_current;
  97. return __tmp;
  98. }
  99. __iterator_tracker&
  100. operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT
  101. {
  102. _M_current = __x._M_current;
  103. _M_ds = __x._M_ds;
  104. return *this;
  105. }
  106. reference
  107. operator*() const _GLIBCXX_NOEXCEPT
  108. { return *_M_current; }
  109. // ------ Random access iterator requirements ------
  110. reference
  111. operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
  112. { return _M_current[__n]; }
  113. __iterator_tracker&
  114. operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
  115. {
  116. _M_current += __n;
  117. return *this;
  118. }
  119. __iterator_tracker
  120. operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
  121. {
  122. __iterator_tracker __tmp(*this);
  123. __tmp += __n;
  124. return __tmp;
  125. }
  126. __iterator_tracker&
  127. operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
  128. {
  129. _M_current += -__n;
  130. return *this;
  131. }
  132. __iterator_tracker
  133. operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
  134. {
  135. __iterator_tracker __tmp(*this);
  136. __tmp -= __n;
  137. return __tmp;
  138. }
  139. const _Sequence*
  140. _M_get_sequence() const
  141. { return static_cast<const _Sequence*>(_M_ds); }
  142. };
  143. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  144. inline bool
  145. operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  146. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  147. _GLIBCXX_NOEXCEPT
  148. { return __lhs.base() == __rhs.base(); }
  149. template<typename _Iterator, typename _Sequence>
  150. inline bool
  151. operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  152. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  153. _GLIBCXX_NOEXCEPT
  154. { return __lhs.base() == __rhs.base(); }
  155. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  156. inline bool
  157. operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  158. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  159. _GLIBCXX_NOEXCEPT
  160. { return __lhs.base() != __rhs.base(); }
  161. template<typename _Iterator, typename _Sequence>
  162. inline bool
  163. operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  164. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  165. _GLIBCXX_NOEXCEPT
  166. { return __lhs.base() != __rhs.base(); }
  167. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  168. inline bool
  169. operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  170. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  171. _GLIBCXX_NOEXCEPT
  172. { return __lhs.base() < __rhs.base(); }
  173. template<typename _Iterator, typename _Sequence>
  174. inline bool
  175. operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  176. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  177. _GLIBCXX_NOEXCEPT
  178. { return __lhs.base() < __rhs.base(); }
  179. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  180. inline bool
  181. operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  182. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  183. _GLIBCXX_NOEXCEPT
  184. { return __lhs.base() <= __rhs.base(); }
  185. template<typename _Iterator, typename _Sequence>
  186. inline bool
  187. operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  188. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  189. _GLIBCXX_NOEXCEPT
  190. { return __lhs.base() <= __rhs.base(); }
  191. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  192. inline bool
  193. operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  194. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  195. _GLIBCXX_NOEXCEPT
  196. { return __lhs.base() > __rhs.base(); }
  197. template<typename _Iterator, typename _Sequence>
  198. inline bool
  199. operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  200. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  201. _GLIBCXX_NOEXCEPT
  202. { return __lhs.base() > __rhs.base(); }
  203. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  204. inline bool
  205. operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  206. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  207. _GLIBCXX_NOEXCEPT
  208. { return __lhs.base() >= __rhs.base(); }
  209. template<typename _Iterator, typename _Sequence>
  210. inline bool
  211. operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  212. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  213. _GLIBCXX_NOEXCEPT
  214. { return __lhs.base() >= __rhs.base(); }
  215. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  216. // According to the resolution of DR179 not only the various comparison
  217. // operators but also operator- must accept mixed iterator/const_iterator
  218. // parameters.
  219. template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  220. inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
  221. operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
  222. const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
  223. _GLIBCXX_NOEXCEPT
  224. { return __lhs.base() - __rhs.base(); }
  225. template<typename _Iterator, typename _Sequence>
  226. inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
  227. operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
  228. const __iterator_tracker<_Iterator, _Sequence>& __rhs)
  229. _GLIBCXX_NOEXCEPT
  230. { return __lhs.base() - __rhs.base(); }
  231. template<typename _Iterator, typename _Sequence>
  232. inline __iterator_tracker<_Iterator, _Sequence>
  233. operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
  234. __n,
  235. const __iterator_tracker<_Iterator, _Sequence>& __i)
  236. _GLIBCXX_NOEXCEPT
  237. { return __i + __n; }
  238. } // namespace __profile
  239. } // namespace std
  240. #endif