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 _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() 60 : _M_current(), _M_ds(0) { } 61 62 __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) 63 : _M_current(__i), _M_ds(__seq) { } 64 65 __iterator_tracker(const __iterator_tracker& __x) 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) 74 : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } 75 76 _Iterator 77 base() const { 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 { return _M_current; } 84 85 pointer 86 operator->() const { return &*_M_current; } 87 88 __iterator_tracker& 89 operator++() 90 { 91 _M_ds->_M_profile_iterate(); 92 ++_M_current; 93 return *this; 94 } 95 96 __iterator_tracker& 97 operator++(int) 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--() 107 { 108 _M_ds->_M_profile_iterate(1); 109 --_M_current; 110 return *this; 111 } 112 113 __iterator_tracker& 114 operator--(int) 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) 124 { 125 _M_current = __x._M_current; 126 return *this; 127 } 128 129 reference 130 operator*() const 131 { return *_M_current; } 132 133 // ------ Random access iterator requirements ------ 134 reference 135 operator[](const difference_type& __n) const 136 { return _M_current[__n]; } 137 138 __iterator_tracker& 139 operator+=(const difference_type& __n) 140 { 141 _M_current += __n; 142 return *this; 143 } 144 145 __iterator_tracker 146 operator+(const difference_type& __n) const 147 { 148 __iterator_tracker __tmp(*this); 149 __tmp += __n; 150 return __tmp; 151 } 152 153 __iterator_tracker& 154 operator-=(const difference_type& __n) 155 { 156 _M_current += -__n; 157 return *this; 158 } 159 160 __iterator_tracker 161 operator-(const difference_type& __n) const 162 { 163 __iterator_tracker __tmp(*this); 164 __tmp -= __n; 165 return __tmp; 166 } 167 168 void 169 _M_find() 170 { _M_ds->_M_profile_find(); } 171 172 const _Sequence* 173 _M_get_sequence() const 174 { return static_cast<const _Sequence*>(_M_ds); } 175 }; 176 177 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 178 inline bool 179 operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 180 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 181 { return __lhs.base() == __rhs.base(); } 182 183 template<typename _Iterator, typename _Sequence> 184 inline bool 185 operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 186 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 187 { return __lhs.base() == __rhs.base(); } 188 189 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 190 inline bool 191 operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 192 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 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 { return __lhs.base() != __rhs.base(); } 200 201 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 202 inline bool 203 operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 204 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 205 { return __lhs.base() < __rhs.base(); } 206 207 template<typename _Iterator, typename _Sequence> 208 inline bool 209 operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 210 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 211 { return __lhs.base() < __rhs.base(); } 212 213 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 214 inline bool 215 operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 216 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 217 { return __lhs.base() <= __rhs.base(); } 218 219 template<typename _Iterator, typename _Sequence> 220 inline bool 221 operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 222 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 223 { return __lhs.base() <= __rhs.base(); } 224 225 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 226 inline bool 227 operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 228 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 229 { return __lhs.base() > __rhs.base(); } 230 231 template<typename _Iterator, typename _Sequence> 232 inline bool 233 operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 234 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 235 { return __lhs.base() > __rhs.base(); } 236 237 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 238 inline bool 239 operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 240 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 241 { return __lhs.base() >= __rhs.base(); } 242 243 template<typename _Iterator, typename _Sequence> 244 inline bool 245 operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 246 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 247 { return __lhs.base() >= __rhs.base(); } 248 249 // _GLIBCXX_RESOLVE_LIB_DEFECTS 250 // According to the resolution of DR179 not only the various comparison 251 // operators but also operator- must accept mixed iterator/const_iterator 252 // parameters. 253 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 254 inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type 255 operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 256 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 257 { return __lhs.base() - __rhs.base(); } 258 259 template<typename _Iterator, typename _Sequence> 260 inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type 261 operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 262 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 263 { return __lhs.base() - __rhs.base(); } 264 265 template<typename _Iterator, typename _Sequence> 266 inline __iterator_tracker<_Iterator, _Sequence> 267 operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type 268 __n, 269 const __iterator_tracker<_Iterator, _Sequence>& __i) 270 { return __i + __n; } 271 272 } // namespace __profile 273 } // namespace std 274 #endif 275