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