Home | History | Annotate | Download | only in profile
      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