1 // Profiling iterator implementation -*- C++ -*- 2 3 // Copyright (C) 2009, 2010 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 35 { 36 namespace __profile 37 { 38 39 template<typename _Iterator, typename _Sequence> 40 class __iterator_tracker 41 { 42 typedef __iterator_tracker _Self; 43 // The underlying iterator 44 _Iterator _M_current; 45 // The underlying data structure 46 const _Sequence* _M_ds; 47 typedef std::iterator_traits<_Iterator> _Traits; 48 49 public: 50 typedef _Iterator _Base_iterator; 51 typedef typename _Traits::iterator_category iterator_category; 52 typedef typename _Traits::value_type value_type; 53 typedef typename _Traits::difference_type difference_type; 54 typedef typename _Traits::reference reference; 55 typedef typename _Traits::pointer pointer; 56 57 __iterator_tracker() : _M_current(), _M_ds(0) { } 58 __iterator_tracker(const _Iterator& __i, const _Sequence* seq) 59 : _M_current(__i), _M_ds(seq) { } 60 __iterator_tracker(const __iterator_tracker& __x) 61 : _M_current(__x._M_current), _M_ds(__x._M_ds) { } 62 template<typename _MutableIterator> 63 __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x) 64 : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } 65 66 _Iterator 67 base() const { return _M_current; } 68 /** 69 * @brief Conversion to underlying non-debug iterator to allow 70 * better interaction with non-profile containers. 71 */ 72 operator _Iterator() const { return _M_current; } 73 74 pointer 75 operator->() const { return &*_M_current; } 76 77 __iterator_tracker& 78 operator++() 79 { 80 _M_ds->_M_profile_iterate(); 81 ++_M_current; 82 return *this; 83 } 84 85 __iterator_tracker& 86 operator++(int) 87 { 88 _M_ds->_M_profile_iterate(); 89 __iterator_tracker __tmp(*this); 90 ++_M_current; 91 return __tmp; 92 } 93 94 __iterator_tracker& 95 operator--() 96 { 97 _M_ds->_M_profile_iterate(1); 98 --_M_current; 99 return *this; 100 } 101 102 __iterator_tracker& 103 operator--(int) 104 { 105 _M_ds->_M_profile_iterate(1); 106 __iterator_tracker __tmp(*this); 107 --_M_current; 108 return __tmp; 109 } 110 111 __iterator_tracker& 112 operator=(const __iterator_tracker& __x) 113 { 114 _M_current = __x._M_current; 115 return *this; 116 } 117 118 reference 119 operator*() const 120 { 121 return *_M_current; 122 } 123 124 // ------ Random access iterator requirements ------ 125 reference 126 operator[](const difference_type& __n) const 127 { 128 return _M_current[__n]; 129 } 130 131 __iterator_tracker& 132 operator+=(const difference_type& __n) 133 { 134 _M_current += __n; 135 return *this; 136 } 137 138 __iterator_tracker 139 operator+(const difference_type& __n) const 140 { 141 __iterator_tracker __tmp(*this); 142 __tmp += __n; 143 return __tmp; 144 } 145 146 __iterator_tracker& 147 operator-=(const difference_type& __n) 148 { 149 _M_current += -__n; 150 return *this; 151 } 152 153 __iterator_tracker 154 operator-(const difference_type& __n) const 155 { 156 __iterator_tracker __tmp(*this); 157 __tmp -= __n; 158 return __tmp; 159 } 160 161 void 162 _M_find() 163 { 164 _M_ds->_M_profile_find(); 165 } 166 167 const _Sequence* 168 _M_get_sequence() const 169 { 170 return static_cast<const _Sequence*>(_M_ds); 171 } 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 { 179 return __lhs.base() == __rhs.base(); 180 } 181 182 template<typename _Iterator, typename _Sequence> 183 inline bool 184 operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 185 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 186 { 187 return __lhs.base() == __rhs.base(); 188 } 189 190 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 191 inline bool 192 operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 193 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 194 { 195 return __lhs.base() != __rhs.base(); 196 } 197 198 template<typename _Iterator, typename _Sequence> 199 inline bool 200 operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 201 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 202 { 203 return __lhs.base() != __rhs.base(); 204 } 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 { 211 return __lhs.base() < __rhs.base(); 212 } 213 214 template<typename _Iterator, typename _Sequence> 215 inline bool 216 operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 217 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 218 { 219 return __lhs.base() < __rhs.base(); 220 } 221 222 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 223 inline bool 224 operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 225 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 226 { 227 return __lhs.base() <= __rhs.base(); 228 } 229 230 template<typename _Iterator, typename _Sequence> 231 inline bool 232 operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 233 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 234 { 235 return __lhs.base() <= __rhs.base(); 236 } 237 238 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 239 inline bool 240 operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 241 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 242 { 243 return __lhs.base() > __rhs.base(); 244 } 245 246 template<typename _Iterator, typename _Sequence> 247 inline bool 248 operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 249 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 250 { 251 return __lhs.base() > __rhs.base(); 252 } 253 254 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 255 inline bool 256 operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 257 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 258 { 259 return __lhs.base() >= __rhs.base(); 260 } 261 262 template<typename _Iterator, typename _Sequence> 263 inline bool 264 operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 265 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 266 { 267 return __lhs.base() >= __rhs.base(); 268 } 269 270 // _GLIBCXX_RESOLVE_LIB_DEFECTS 271 // According to the resolution of DR179 not only the various comparison 272 // operators but also operator- must accept mixed iterator/const_iterator 273 // parameters. 274 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 275 inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type 276 operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 277 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 278 { 279 return __lhs.base() - __rhs.base(); 280 } 281 282 template<typename _Iterator, typename _Sequence> 283 inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type 284 operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 285 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 286 { 287 return __lhs.base() - __rhs.base(); 288 } 289 290 template<typename _Iterator, typename _Sequence> 291 inline __iterator_tracker<_Iterator, _Sequence> 292 operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type 293 __n, 294 const __iterator_tracker<_Iterator, _Sequence>& __i) 295 { 296 return __i + __n; 297 } 298 299 } // namespace __profile 300 } // namespace std 301 #endif 302