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
00035 {
00036 namespace __profile
00037 {
00038 
00039 template<typename _Iterator, typename _Sequence>
00040 class __iterator_tracker 
00041 {
00042   typedef __iterator_tracker _Self;
00043   // The underlying iterator
00044   _Iterator _M_current;
00045   // The underlying data structure
00046   const _Sequence* _M_ds;
00047   typedef std::iterator_traits<_Iterator> _Traits;
00048 
00049  public:
00050   typedef _Iterator                   _Base_iterator;
00051   typedef typename _Traits::iterator_category iterator_category; 
00052   typedef typename _Traits::value_type        value_type;
00053   typedef typename _Traits::difference_type   difference_type;
00054   typedef typename _Traits::reference         reference;
00055   typedef typename _Traits::pointer           pointer;
00056 
00057   __iterator_tracker() : _M_current(), _M_ds(0) { }
00058   __iterator_tracker(const _Iterator& __i, const _Sequence* seq) 
00059       : _M_current(__i), _M_ds(seq) { }
00060   __iterator_tracker(const __iterator_tracker& __x) 
00061       : _M_current(__x._M_current), _M_ds(__x._M_ds) { }
00062   template<typename _MutableIterator>
00063   __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x)
00064       :  _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
00065 
00066   _Iterator
00067   base() const { return _M_current; }
00068   /**
00069    * @brief Conversion to underlying non-debug iterator to allow
00070    * better interaction with non-profile containers.
00071    */
00072   operator _Iterator() const { return _M_current; }
00073 
00074   pointer
00075   operator->() const { return &*_M_current; }
00076 
00077   __iterator_tracker&
00078   operator++()
00079   {
00080     _M_ds->_M_profile_iterate();
00081     ++_M_current;
00082     return *this;
00083   }
00084 
00085   __iterator_tracker&
00086   operator++(int)
00087   {
00088     _M_ds->_M_profile_iterate();
00089     __iterator_tracker __tmp(*this);
00090     ++_M_current;
00091     return __tmp;
00092   }
00093 
00094   __iterator_tracker&
00095   operator--()
00096   {
00097     _M_ds->_M_profile_iterate(1);
00098     --_M_current;
00099     return *this;
00100   }
00101 
00102   __iterator_tracker&
00103   operator--(int)
00104   {
00105     _M_ds->_M_profile_iterate(1);
00106     __iterator_tracker __tmp(*this);
00107     --_M_current;
00108     return __tmp;
00109   }
00110 
00111   __iterator_tracker&
00112   operator=(const __iterator_tracker& __x)
00113   {
00114     _M_current = __x._M_current;
00115     return *this;
00116   }
00117 
00118   reference
00119   operator*() const
00120   {
00121     return *_M_current;
00122   }
00123 
00124  // ------ Random access iterator requirements ------
00125   reference
00126   operator[](const difference_type& __n) const 
00127   {
00128     return _M_current[__n];
00129   }
00130 
00131   __iterator_tracker&
00132   operator+=(const difference_type& __n)
00133   {
00134     _M_current += __n;
00135     return *this;
00136   }
00137 
00138   __iterator_tracker
00139   operator+(const difference_type& __n) const
00140   {
00141     __iterator_tracker __tmp(*this);
00142     __tmp += __n;
00143     return __tmp;
00144   }
00145 
00146   __iterator_tracker&
00147   operator-=(const difference_type& __n)
00148   {
00149     _M_current += -__n;
00150     return *this;
00151   }
00152 
00153   __iterator_tracker
00154   operator-(const difference_type& __n) const
00155   {
00156     __iterator_tracker __tmp(*this);
00157     __tmp -= __n;
00158     return __tmp;
00159   }
00160 
00161   void
00162   _M_find()
00163   {
00164     _M_ds->_M_profile_find();
00165   }
00166 
00167   const _Sequence*
00168   _M_get_sequence() const
00169   {
00170     return static_cast<const _Sequence*>(_M_ds);
00171   }
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 {
00179   return __lhs.base() == __rhs.base();
00180 }
00181 
00182 template<typename _Iterator, typename _Sequence>
00183 inline bool
00184 operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00185            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00186 {
00187   return __lhs.base() == __rhs.base();
00188 }
00189 
00190 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00191 inline bool
00192 operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00193            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00194 {
00195   return __lhs.base() != __rhs.base();
00196 }
00197 
00198 template<typename _Iterator, typename _Sequence>
00199 inline bool
00200 operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00201                const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00202 {
00203   return __lhs.base() != __rhs.base();
00204 }
00205 
00206 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00207 inline bool
00208 operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00209           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00210 {
00211   return __lhs.base() < __rhs.base();
00212 }
00213 
00214 template<typename _Iterator, typename _Sequence>
00215 inline bool
00216 operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00217           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00218 {
00219   return __lhs.base() < __rhs.base();
00220 }
00221 
00222 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00223 inline bool
00224 operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00225            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00226 {
00227   return __lhs.base() <= __rhs.base();
00228 }
00229 
00230 template<typename _Iterator, typename _Sequence>
00231 inline bool
00232 operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00233            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00234 {
00235   return __lhs.base() <= __rhs.base();
00236 }
00237 
00238 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00239 inline bool
00240 operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00241           const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00242 {
00243   return __lhs.base() > __rhs.base();
00244 }
00245 
00246 template<typename _Iterator, typename _Sequence>
00247 inline bool
00248 operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00249           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00250 {
00251   return __lhs.base() > __rhs.base();
00252 }
00253 
00254 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00255 inline bool
00256 operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00257            const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00258 {
00259   return __lhs.base() >= __rhs.base();
00260 }
00261 
00262 template<typename _Iterator, typename _Sequence>
00263 inline bool
00264 operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00265            const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00266 {
00267   return __lhs.base() >= __rhs.base();
00268 }
00269 
00270 // _GLIBCXX_RESOLVE_LIB_DEFECTS
00271 // According to the resolution of DR179 not only the various comparison
00272 // operators but also operator- must accept mixed iterator/const_iterator
00273 // parameters.
00274   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00275   inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
00276   operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
00277             const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
00278 {
00279   return __lhs.base() - __rhs.base();
00280 }
00281 
00282 template<typename _Iterator, typename _Sequence>
00283 inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
00284 operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
00285           const __iterator_tracker<_Iterator, _Sequence>& __rhs)
00286 {
00287   return __lhs.base() - __rhs.base();
00288 }
00289 
00290 template<typename _Iterator, typename _Sequence>
00291 inline __iterator_tracker<_Iterator, _Sequence>
00292 operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
00293           __n,
00294           const __iterator_tracker<_Iterator, _Sequence>& __i)
00295 {
00296   return __i + __n;
00297 }
00298         
00299 }  // namespace __profile
00300 }  // namespace std
00301 #endif