libstdc++
iterator_tracker.h
Go to the documentation of this file.
00001 // Profiling iterator implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2009-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file profile/iterator_tracker.h
00026  *  This file is a GNU profile extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER
00030 #define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1
00031 
00032 #include <ext/type_traits.h>
00033 
00034 namespace std _GLIBCXX_VISIBILITY(default)
00035 {
00036 namespace __profile
00037 {
00038   template<typename _Iterator, typename _Sequence>
00039     class __iterator_tracker
00040     {
00041       typedef __iterator_tracker _Self;
00042 
00043       // The underlying iterator
00044       _Iterator _M_current;
00045 
00046       // The underlying data structure
00047       const _Sequence* _M_ds;
00048       typedef std::iterator_traits<_Iterator> _Traits;
00049 
00050     public:
00051       typedef _Iterator                                 _Base_iterator;
00052       typedef typename _Traits::iterator_category       iterator_category;
00053       typedef typename _Traits::value_type              value_type;
00054       typedef typename _Traits::difference_type         difference_type;
00055       typedef typename _Traits::reference               reference;
00056       typedef typename _Traits::pointer                 pointer;
00057 
00058       __iterator_tracker() _GLIBCXX_NOEXCEPT
00059       : _M_current(), _M_ds(0) { }
00060 
00061       __iterator_tracker(const _Iterator& __i, const _Sequence* __seq)
00062       _GLIBCXX_NOEXCEPT
00063       : _M_current(__i), _M_ds(__seq) { }
00064 
00065       __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT
00066       : _M_current(__x._M_current), _M_ds(__x._M_ds) { }
00067 
00068       template<typename _MutableIterator>
00069         __iterator_tracker(const __iterator_tracker<_MutableIterator,
00070                            typename __gnu_cxx::__enable_if
00071                            <(std::__are_same<_MutableIterator, typename
00072                              _Sequence::iterator::_Base_iterator>::__value),
00073                            _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
00074         :  _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
00075 
00076       _Iterator
00077       base() const _GLIBCXX_NOEXCEPT { return _M_current; }
00078 
00079       /**
00080        * @brief Conversion to underlying non-debug iterator to allow
00081        * better interaction with non-profile containers.
00082        */
00083       operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; }
00084 
00085       pointer
00086       operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; }
00087 
00088       __iterator_tracker&
00089       operator++() _GLIBCXX_NOEXCEPT
00090       {
00091         _M_ds->_M_profile_iterate();
00092         ++_M_current;
00093         return *this;
00094       }
00095 
00096       __iterator_tracker
00097       operator++(int) _GLIBCXX_NOEXCEPT
00098       {
00099         _M_ds->_M_profile_iterate();
00100         __iterator_tracker __tmp(*this);
00101         ++_M_current;
00102         return __tmp;
00103       }
00104 
00105       __iterator_tracker&
00106       operator--() _GLIBCXX_NOEXCEPT
00107       {
00108         _M_ds->_M_profile_iterate(1);
00109         --_M_current;
00110         return *this;
00111       }
00112 
00113       __iterator_tracker
00114       operator--(int) _GLIBCXX_NOEXCEPT
00115       {
00116         _M_ds->_M_profile_iterate(1);
00117         __iterator_tracker __tmp(*this);
00118         --_M_current;
00119         return __tmp;
00120       }
00121 
00122       __iterator_tracker&
00123       operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT
00124       {
00125         _M_current = __x._M_current;
00126         _M_ds = __x._M_ds;
00127         return *this;
00128       }
00129 
00130       reference
00131       operator*() const _GLIBCXX_NOEXCEPT
00132       { return *_M_current; }
00133 
00134       // ------ Random access iterator requirements ------
00135       reference
00136       operator[](const difference_type& __n) const  _GLIBCXX_NOEXCEPT
00137       { return _M_current[__n]; }
00138 
00139       __iterator_tracker&
00140       operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
00141       {
00142         _M_current += __n;
00143         return *this;
00144       }
00145 
00146       __iterator_tracker
00147       operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
00148       {
00149         __iterator_tracker __tmp(*this);
00150         __tmp += __n;
00151         return __tmp;
00152       }
00153 
00154       __iterator_tracker&
00155       operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
00156       {
00157         _M_current += -__n;
00158         return *this;
00159       }
00160 
00161       __iterator_tracker
00162       operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
00163       {
00164         __iterator_tracker __tmp(*this);
00165         __tmp -= __n;
00166         return __tmp;
00167       }
00168 
00169       const _Sequence*
00170       _M_get_sequence() const
00171       { return static_cast<const _Sequence*>(_M_ds); }
00172   };
00173 
00174   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00175     inline bool
00176     operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00177                const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00178     _GLIBCXX_NOEXCEPT
00179     { return __lhs.base() == __rhs.base(); }
00180 
00181   template<typename _Iterator, typename _Sequence>
00182     inline bool
00183     operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00184                const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00185     _GLIBCXX_NOEXCEPT
00186     { return __lhs.base() == __rhs.base(); }
00187 
00188   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00189     inline bool
00190     operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00191                const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00192     _GLIBCXX_NOEXCEPT
00193     { return __lhs.base() != __rhs.base(); }
00194 
00195   template<typename _Iterator, typename _Sequence>
00196     inline bool
00197     operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00198                const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00199     _GLIBCXX_NOEXCEPT
00200     { return __lhs.base() != __rhs.base(); }
00201 
00202   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00203     inline bool
00204     operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00205               const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00206     _GLIBCXX_NOEXCEPT
00207     { return __lhs.base() < __rhs.base(); }
00208 
00209   template<typename _Iterator, typename _Sequence>
00210     inline bool
00211     operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00212               const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00213     _GLIBCXX_NOEXCEPT
00214     { return __lhs.base() < __rhs.base(); }
00215 
00216   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00217     inline bool
00218     operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00219                const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00220     _GLIBCXX_NOEXCEPT
00221     { return __lhs.base() <= __rhs.base(); }
00222 
00223   template<typename _Iterator, typename _Sequence>
00224     inline bool
00225     operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00226                const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00227     _GLIBCXX_NOEXCEPT
00228     { return __lhs.base() <= __rhs.base(); }
00229 
00230   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00231     inline bool
00232     operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00233               const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00234     _GLIBCXX_NOEXCEPT
00235     { return __lhs.base() > __rhs.base(); }
00236 
00237   template<typename _Iterator, typename _Sequence>
00238     inline bool
00239     operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00240               const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00241     _GLIBCXX_NOEXCEPT
00242     { return __lhs.base() > __rhs.base(); }
00243 
00244   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00245     inline bool
00246     operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00247                const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00248     _GLIBCXX_NOEXCEPT
00249     { return __lhs.base() >= __rhs.base(); }
00250 
00251   template<typename _Iterator, typename _Sequence>
00252     inline bool
00253     operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00254                const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00255     _GLIBCXX_NOEXCEPT
00256     { return __lhs.base() >= __rhs.base(); }
00257 
00258   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00259   // According to the resolution of DR179 not only the various comparison
00260   // operators but also operator- must accept mixed iterator/const_iterator
00261   // parameters.
00262   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00263     inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
00264     operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00265               const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00266     _GLIBCXX_NOEXCEPT
00267     { return __lhs.base() - __rhs.base(); }
00268 
00269   template<typename _Iterator, typename _Sequence>
00270     inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
00271     operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00272               const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00273     _GLIBCXX_NOEXCEPT
00274     { return __lhs.base() - __rhs.base(); }
00275 
00276   template<typename _Iterator, typename _Sequence>
00277     inline __iterator_tracker<_Iterator, _Sequence>
00278     operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
00279               __n,
00280               const __iterator_tracker<_Iterator, _Sequence>& __i)
00281     _GLIBCXX_NOEXCEPT
00282     { return __i + __n; }
00283         
00284 }  // namespace __profile
00285 }  // namespace std
00286 #endif