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