libstdc++
|
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