1 // Profiling iterator implementation -*- C++ -*- 2 3 // Copyright (C) 2009-2014 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 39 template<typename _Iterator, typename _Sequence> 40 class __iterator_tracker 41 { 42 typedef __iterator_tracker _Self; 43 44 // The underlying iterator 45 _Iterator _M_current; 46 47 // The underlying data structure 48 const _Sequence* _M_ds; 49 typedef std::iterator_traits<_Iterator> _Traits; 50 51 public: 52 typedef _Iterator _Base_iterator; 53 typedef typename _Traits::iterator_category iterator_category; 54 typedef typename _Traits::value_type value_type; 55 typedef typename _Traits::difference_type difference_type; 56 typedef typename _Traits::reference reference; 57 typedef typename _Traits::pointer pointer; 58 59 __iterator_tracker() _GLIBCXX_NOEXCEPT 60 : _M_current(), _M_ds(0) { } 61 62 __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) 63 _GLIBCXX_NOEXCEPT 64 : _M_current(__i), _M_ds(__seq) { } 65 66 __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT 67 : _M_current(__x._M_current), _M_ds(__x._M_ds) { } 68 69 template<typename _MutableIterator> 70 __iterator_tracker(const __iterator_tracker<_MutableIterator, 71 typename __gnu_cxx::__enable_if 72 <(std::__are_same<_MutableIterator, typename 73 _Sequence::iterator::_Base_iterator>::__value), 74 _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT 75 : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } 76 77 _Iterator 78 base() const _GLIBCXX_NOEXCEPT { return _M_current; } 79 80 /** 81 * @brief Conversion to underlying non-debug iterator to allow 82 * better interaction with non-profile containers. 83 */ 84 operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } 85 86 pointer 87 operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; } 88 89 __iterator_tracker& 90 operator++() _GLIBCXX_NOEXCEPT 91 { 92 _M_ds->_M_profile_iterate(); 93 ++_M_current; 94 return *this; 95 } 96 97 __iterator_tracker 98 operator++(int) _GLIBCXX_NOEXCEPT 99 { 100 _M_ds->_M_profile_iterate(); 101 __iterator_tracker __tmp(*this); 102 ++_M_current; 103 return __tmp; 104 } 105 106 __iterator_tracker& 107 operator--() _GLIBCXX_NOEXCEPT 108 { 109 _M_ds->_M_profile_iterate(1); 110 --_M_current; 111 return *this; 112 } 113 114 __iterator_tracker 115 operator--(int) _GLIBCXX_NOEXCEPT 116 { 117 _M_ds->_M_profile_iterate(1); 118 __iterator_tracker __tmp(*this); 119 --_M_current; 120 return __tmp; 121 } 122 123 __iterator_tracker& 124 operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT 125 { 126 _M_current = __x._M_current; 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 void 170 _M_find() 171 { _M_ds->_M_profile_find(); } 172 173 const _Sequence* 174 _M_get_sequence() const 175 { return static_cast<const _Sequence*>(_M_ds); } 176 }; 177 178 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 179 inline bool 180 operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 181 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 182 _GLIBCXX_NOEXCEPT 183 { return __lhs.base() == __rhs.base(); } 184 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 192 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 193 inline bool 194 operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 195 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 196 _GLIBCXX_NOEXCEPT 197 { return __lhs.base() != __rhs.base(); } 198 199 template<typename _Iterator, typename _Sequence> 200 inline bool 201 operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 202 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 203 _GLIBCXX_NOEXCEPT 204 { return __lhs.base() != __rhs.base(); } 205 206 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 207 inline bool 208 operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 209 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 210 _GLIBCXX_NOEXCEPT 211 { return __lhs.base() < __rhs.base(); } 212 213 template<typename _Iterator, typename _Sequence> 214 inline bool 215 operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 216 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 217 _GLIBCXX_NOEXCEPT 218 { return __lhs.base() < __rhs.base(); } 219 220 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 221 inline bool 222 operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 223 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 224 _GLIBCXX_NOEXCEPT 225 { return __lhs.base() <= __rhs.base(); } 226 227 template<typename _Iterator, typename _Sequence> 228 inline bool 229 operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 230 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 231 _GLIBCXX_NOEXCEPT 232 { return __lhs.base() <= __rhs.base(); } 233 234 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 235 inline bool 236 operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 237 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 238 _GLIBCXX_NOEXCEPT 239 { return __lhs.base() > __rhs.base(); } 240 241 template<typename _Iterator, typename _Sequence> 242 inline bool 243 operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 244 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 245 _GLIBCXX_NOEXCEPT 246 { return __lhs.base() > __rhs.base(); } 247 248 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 249 inline bool 250 operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 251 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 252 _GLIBCXX_NOEXCEPT 253 { return __lhs.base() >= __rhs.base(); } 254 255 template<typename _Iterator, typename _Sequence> 256 inline bool 257 operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 258 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 259 _GLIBCXX_NOEXCEPT 260 { return __lhs.base() >= __rhs.base(); } 261 262 // _GLIBCXX_RESOLVE_LIB_DEFECTS 263 // According to the resolution of DR179 not only the various comparison 264 // operators but also operator- must accept mixed iterator/const_iterator 265 // parameters. 266 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 267 inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type 268 operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 269 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 270 _GLIBCXX_NOEXCEPT 271 { return __lhs.base() - __rhs.base(); } 272 273 template<typename _Iterator, typename _Sequence> 274 inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type 275 operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 276 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 277 _GLIBCXX_NOEXCEPT 278 { return __lhs.base() - __rhs.base(); } 279 280 template<typename _Iterator, typename _Sequence> 281 inline __iterator_tracker<_Iterator, _Sequence> 282 operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type 283 __n, 284 const __iterator_tracker<_Iterator, _Sequence>& __i) 285 _GLIBCXX_NOEXCEPT 286 { return __i + __n; } 287 288 } // namespace __profile 289 } // namespace std 290 #endif 291