libstdc++
|
00001 // Profiling iterator implementation -*- C++ -*- 00002 00003 // Copyright (C) 2009-2014 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() _GLIBCXX_NOEXCEPT 00060 : _M_current(), _M_ds(0) { } 00061 00062 __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) 00063 _GLIBCXX_NOEXCEPT 00064 : _M_current(__i), _M_ds(__seq) { } 00065 00066 __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT 00067 : _M_current(__x._M_current), _M_ds(__x._M_ds) { } 00068 00069 template<typename _MutableIterator> 00070 __iterator_tracker(const __iterator_tracker<_MutableIterator, 00071 typename __gnu_cxx::__enable_if 00072 <(std::__are_same<_MutableIterator, typename 00073 _Sequence::iterator::_Base_iterator>::__value), 00074 _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT 00075 : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } 00076 00077 _Iterator 00078 base() const _GLIBCXX_NOEXCEPT { return _M_current; } 00079 00080 /** 00081 * @brief Conversion to underlying non-debug iterator to allow 00082 * better interaction with non-profile containers. 00083 */ 00084 operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } 00085 00086 pointer 00087 operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; } 00088 00089 __iterator_tracker& 00090 operator++() _GLIBCXX_NOEXCEPT 00091 { 00092 _M_ds->_M_profile_iterate(); 00093 ++_M_current; 00094 return *this; 00095 } 00096 00097 __iterator_tracker 00098 operator++(int) _GLIBCXX_NOEXCEPT 00099 { 00100 _M_ds->_M_profile_iterate(); 00101 __iterator_tracker __tmp(*this); 00102 ++_M_current; 00103 return __tmp; 00104 } 00105 00106 __iterator_tracker& 00107 operator--() _GLIBCXX_NOEXCEPT 00108 { 00109 _M_ds->_M_profile_iterate(1); 00110 --_M_current; 00111 return *this; 00112 } 00113 00114 __iterator_tracker 00115 operator--(int) _GLIBCXX_NOEXCEPT 00116 { 00117 _M_ds->_M_profile_iterate(1); 00118 __iterator_tracker __tmp(*this); 00119 --_M_current; 00120 return __tmp; 00121 } 00122 00123 __iterator_tracker& 00124 operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT 00125 { 00126 _M_current = __x._M_current; 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 void 00170 _M_find() 00171 { _M_ds->_M_profile_find(); } 00172 00173 const _Sequence* 00174 _M_get_sequence() const 00175 { return static_cast<const _Sequence*>(_M_ds); } 00176 }; 00177 00178 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00179 inline bool 00180 operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00181 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00182 _GLIBCXX_NOEXCEPT 00183 { return __lhs.base() == __rhs.base(); } 00184 00185 template<typename _Iterator, typename _Sequence> 00186 inline bool 00187 operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00188 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00189 _GLIBCXX_NOEXCEPT 00190 { return __lhs.base() == __rhs.base(); } 00191 00192 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00193 inline bool 00194 operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00195 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00196 _GLIBCXX_NOEXCEPT 00197 { return __lhs.base() != __rhs.base(); } 00198 00199 template<typename _Iterator, typename _Sequence> 00200 inline bool 00201 operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00202 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00203 _GLIBCXX_NOEXCEPT 00204 { return __lhs.base() != __rhs.base(); } 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 _GLIBCXX_NOEXCEPT 00211 { return __lhs.base() < __rhs.base(); } 00212 00213 template<typename _Iterator, typename _Sequence> 00214 inline bool 00215 operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00216 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00217 _GLIBCXX_NOEXCEPT 00218 { return __lhs.base() < __rhs.base(); } 00219 00220 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00221 inline bool 00222 operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00223 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00224 _GLIBCXX_NOEXCEPT 00225 { return __lhs.base() <= __rhs.base(); } 00226 00227 template<typename _Iterator, typename _Sequence> 00228 inline bool 00229 operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00230 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00231 _GLIBCXX_NOEXCEPT 00232 { return __lhs.base() <= __rhs.base(); } 00233 00234 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00235 inline bool 00236 operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00237 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00238 _GLIBCXX_NOEXCEPT 00239 { return __lhs.base() > __rhs.base(); } 00240 00241 template<typename _Iterator, typename _Sequence> 00242 inline bool 00243 operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00244 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00245 _GLIBCXX_NOEXCEPT 00246 { return __lhs.base() > __rhs.base(); } 00247 00248 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00249 inline bool 00250 operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00251 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00252 _GLIBCXX_NOEXCEPT 00253 { return __lhs.base() >= __rhs.base(); } 00254 00255 template<typename _Iterator, typename _Sequence> 00256 inline bool 00257 operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00258 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00259 _GLIBCXX_NOEXCEPT 00260 { return __lhs.base() >= __rhs.base(); } 00261 00262 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00263 // According to the resolution of DR179 not only the various comparison 00264 // operators but also operator- must accept mixed iterator/const_iterator 00265 // parameters. 00266 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00267 inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type 00268 operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, 00269 const __iterator_tracker<_IteratorR, _Sequence>& __rhs) 00270 _GLIBCXX_NOEXCEPT 00271 { return __lhs.base() - __rhs.base(); } 00272 00273 template<typename _Iterator, typename _Sequence> 00274 inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type 00275 operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, 00276 const __iterator_tracker<_Iterator, _Sequence>& __rhs) 00277 _GLIBCXX_NOEXCEPT 00278 { return __lhs.base() - __rhs.base(); } 00279 00280 template<typename _Iterator, typename _Sequence> 00281 inline __iterator_tracker<_Iterator, _Sequence> 00282 operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type 00283 __n, 00284 const __iterator_tracker<_Iterator, _Sequence>& __i) 00285 _GLIBCXX_NOEXCEPT 00286 { return __i + __n; } 00287 00288 } // namespace __profile 00289 } // namespace std 00290 #endif