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