libstdc++
iterator_tracker.h
Go to the documentation of this file.
00001 // Profiling iterator implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2009, 2010 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 
00039   template<typename _Iterator, typename _Sequence>
00040     class __iterator_tracker 
00041     {
00042       typedef __iterator_tracker _Self;
00043 
00044       // The underlying iterator
00045       _Iterator _M_current;
00046 
00047       // The underlying data structure
00048       const _Sequence* _M_ds;
00049       typedef std::iterator_traits<_Iterator> _Traits;
00050 
00051     public:
00052       typedef _Iterator                   _Base_iterator;
00053       typedef typename _Traits::iterator_category iterator_category; 
00054       typedef typename _Traits::value_type        value_type;
00055       typedef typename _Traits::difference_type   difference_type;
00056       typedef typename _Traits::reference         reference;
00057       typedef typename _Traits::pointer           pointer;
00058 
00059       __iterator_tracker()
00060       : _M_current(), _M_ds(0) { }
00061 
00062       __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) 
00063       : _M_current(__i), _M_ds(__seq) { }
00064 
00065       __iterator_tracker(const __iterator_tracker& __x) 
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)
00074     :  _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
00075 
00076       _Iterator
00077       base() const { 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 { return _M_current; }
00084 
00085       pointer
00086       operator->() const { return &*_M_current; }
00087 
00088       __iterator_tracker&
00089       operator++()
00090       {
00091     _M_ds->_M_profile_iterate();
00092     ++_M_current;
00093     return *this;
00094       }
00095 
00096       __iterator_tracker&
00097       operator++(int)
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--()
00107       {
00108     _M_ds->_M_profile_iterate(1);
00109     --_M_current;
00110     return *this;
00111       }
00112 
00113       __iterator_tracker&
00114       operator--(int)
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)
00124       {
00125     _M_current = __x._M_current;
00126     return *this;
00127       }
00128 
00129       reference
00130       operator*() const
00131       { return *_M_current; }
00132 
00133       // ------ Random access iterator requirements ------
00134       reference
00135       operator[](const difference_type& __n) const 
00136       { return _M_current[__n]; }
00137 
00138       __iterator_tracker&
00139       operator+=(const difference_type& __n)
00140       {
00141     _M_current += __n;
00142     return *this;
00143       }
00144 
00145       __iterator_tracker
00146       operator+(const difference_type& __n) const
00147       {
00148     __iterator_tracker __tmp(*this);
00149     __tmp += __n;
00150     return __tmp;
00151       }
00152 
00153       __iterator_tracker&
00154       operator-=(const difference_type& __n)
00155       {
00156     _M_current += -__n;
00157     return *this;
00158       }
00159 
00160       __iterator_tracker
00161       operator-(const difference_type& __n) const
00162       {
00163     __iterator_tracker __tmp(*this);
00164     __tmp -= __n;
00165     return __tmp;
00166       }
00167 
00168       void
00169       _M_find()
00170       { _M_ds->_M_profile_find(); }
00171 
00172       const _Sequence*
00173       _M_get_sequence() const
00174       { return static_cast<const _Sequence*>(_M_ds); }
00175   };
00176 
00177   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00178     inline bool
00179     operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00180            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00181     { return __lhs.base() == __rhs.base(); }
00182 
00183   template<typename _Iterator, typename _Sequence>
00184     inline bool
00185     operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00186            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00187     { return __lhs.base() == __rhs.base(); }
00188 
00189   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00190     inline bool
00191     operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00192            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
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     { return __lhs.base() != __rhs.base(); }
00200 
00201   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00202     inline bool
00203     operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00204           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00205     { return __lhs.base() < __rhs.base(); }
00206 
00207   template<typename _Iterator, typename _Sequence>
00208     inline bool
00209     operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00210           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00211     { return __lhs.base() < __rhs.base(); }
00212 
00213   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00214     inline bool
00215     operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00216            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00217     { return __lhs.base() <= __rhs.base(); }
00218 
00219   template<typename _Iterator, typename _Sequence>
00220     inline bool
00221     operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00222            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00223     { return __lhs.base() <= __rhs.base(); }
00224 
00225   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00226     inline bool
00227     operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00228           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00229     { return __lhs.base() > __rhs.base(); }
00230 
00231   template<typename _Iterator, typename _Sequence>
00232     inline bool
00233     operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00234           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00235     { return __lhs.base() > __rhs.base(); }
00236 
00237   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00238     inline bool
00239     operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00240            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00241     { return __lhs.base() >= __rhs.base(); }
00242 
00243   template<typename _Iterator, typename _Sequence>
00244     inline bool
00245     operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00246            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00247     { return __lhs.base() >= __rhs.base(); }
00248 
00249   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00250   // According to the resolution of DR179 not only the various comparison
00251   // operators but also operator- must accept mixed iterator/const_iterator
00252   // parameters.
00253   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00254     inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
00255     operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00256           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00257     { return __lhs.base() - __rhs.base(); }
00258 
00259   template<typename _Iterator, typename _Sequence>
00260     inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
00261     operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00262           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00263     { return __lhs.base() - __rhs.base(); }
00264 
00265   template<typename _Iterator, typename _Sequence>
00266     inline __iterator_tracker<_Iterator, _Sequence>
00267     operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
00268           __n,
00269           const __iterator_tracker<_Iterator, _Sequence>& __i)
00270     { return __i + __n; }
00271     
00272 }  // namespace __profile
00273 }  // namespace std
00274 #endif