libstdc++
|
00001 // Profiling list implementation -*- C++ -*- 00002 00003 // Copyright (C) 2009, 2010, 2011 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/list 00026 * This file is a GNU profile extension to the Standard C++ Library. 00027 */ 00028 00029 #ifndef _GLIBCXX_PROFILE_LIST 00030 #define _GLIBCXX_PROFILE_LIST 1 00031 00032 #include <list> 00033 #include <profile/base.h> 00034 #include <profile/iterator_tracker.h> 00035 00036 namespace std _GLIBCXX_VISIBILITY(default) 00037 { 00038 namespace __profile 00039 { 00040 /** @brief List wrapper with performance instrumentation. */ 00041 template<typename _Tp, typename _Allocator = std::allocator<_Tp> > 00042 class list 00043 : public _GLIBCXX_STD_C::list<_Tp, _Allocator> 00044 { 00045 typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base; 00046 00047 public: 00048 typedef typename _Base::reference reference; 00049 typedef typename _Base::const_reference const_reference; 00050 00051 typedef __iterator_tracker<typename _Base::iterator, list> 00052 iterator; 00053 typedef __iterator_tracker<typename _Base::const_iterator, list> 00054 const_iterator; 00055 00056 typedef typename _Base::size_type size_type; 00057 typedef typename _Base::difference_type difference_type; 00058 00059 typedef _Tp value_type; 00060 typedef _Allocator allocator_type; 00061 typedef typename _Base::pointer pointer; 00062 typedef typename _Base::const_pointer const_pointer; 00063 typedef std::reverse_iterator<iterator> reverse_iterator; 00064 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00065 00066 // 23.2.2.1 construct/copy/destroy: 00067 explicit 00068 list(const _Allocator& __a = _Allocator()) 00069 : _Base(__a) 00070 { 00071 __profcxx_list_construct(this); // list2slist 00072 __profcxx_list_construct2(this); // list2vector 00073 } 00074 00075 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00076 explicit 00077 list(size_type __n) 00078 : _Base(__n) 00079 { 00080 __profcxx_list_construct(this); 00081 __profcxx_list_construct2(this); 00082 } 00083 00084 list(size_type __n, const _Tp& __value, 00085 const _Allocator& __a = _Allocator()) 00086 : _Base(__n, __value, __a) 00087 { 00088 __profcxx_list_construct(this); 00089 __profcxx_list_construct2(this); 00090 } 00091 #else 00092 explicit 00093 list(size_type __n, const _Tp& __value = _Tp(), 00094 const _Allocator& __a = _Allocator()) 00095 : _Base(__n, __value, __a) 00096 { 00097 __profcxx_list_construct(this); 00098 __profcxx_list_construct2(this); 00099 } 00100 #endif 00101 00102 template<class _InputIterator> 00103 list(_InputIterator __first, _InputIterator __last, 00104 const _Allocator& __a = _Allocator()) 00105 : _Base(__first, __last, __a) 00106 { 00107 __profcxx_list_construct(this); 00108 __profcxx_list_construct2(this); 00109 } 00110 00111 list(const list& __x) 00112 : _Base(__x) 00113 { 00114 __profcxx_list_construct(this); 00115 __profcxx_list_construct2(this); 00116 } 00117 00118 list(const _Base& __x) 00119 : _Base(__x) 00120 { 00121 __profcxx_list_construct(this); 00122 __profcxx_list_construct2(this); 00123 } 00124 00125 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00126 list(list&& __x) noexcept 00127 : _Base(std::move(__x)) 00128 { 00129 __profcxx_list_construct(this); 00130 __profcxx_list_construct2(this); 00131 } 00132 00133 list(initializer_list<value_type> __l, 00134 const allocator_type& __a = allocator_type()) 00135 : _Base(__l, __a) { } 00136 #endif 00137 00138 ~list() _GLIBCXX_NOEXCEPT 00139 { 00140 __profcxx_list_destruct(this); 00141 __profcxx_list_destruct2(this); 00142 } 00143 00144 list& 00145 operator=(const list& __x) 00146 { 00147 static_cast<_Base&>(*this) = __x; 00148 return *this; 00149 } 00150 00151 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00152 list& 00153 operator=(list&& __x) 00154 { 00155 // NB: DR 1204. 00156 // NB: DR 675. 00157 this->clear(); 00158 this->swap(__x); 00159 return *this; 00160 } 00161 00162 list& 00163 operator=(initializer_list<value_type> __l) 00164 { 00165 static_cast<_Base&>(*this) = __l; 00166 return *this; 00167 } 00168 00169 void 00170 assign(initializer_list<value_type> __l) 00171 { _Base::assign(__l); } 00172 #endif 00173 00174 template<class _InputIterator> 00175 void 00176 assign(_InputIterator __first, _InputIterator __last) 00177 { _Base::assign(__first, __last); } 00178 00179 void 00180 assign(size_type __n, const _Tp& __t) 00181 { _Base::assign(__n, __t); } 00182 00183 using _Base::get_allocator; 00184 00185 // iterators: 00186 iterator 00187 begin() _GLIBCXX_NOEXCEPT 00188 { return iterator(_Base::begin(), this); } 00189 00190 const_iterator 00191 begin() const _GLIBCXX_NOEXCEPT 00192 { return const_iterator(_Base::begin(), this); } 00193 00194 iterator 00195 end() _GLIBCXX_NOEXCEPT 00196 { 00197 __profcxx_list_rewind(this); 00198 return iterator(_Base::end(), this); 00199 } 00200 00201 const_iterator 00202 end() const _GLIBCXX_NOEXCEPT 00203 { 00204 __profcxx_list_rewind(this); 00205 return const_iterator(_Base::end(), this); 00206 } 00207 00208 reverse_iterator 00209 rbegin() _GLIBCXX_NOEXCEPT 00210 { 00211 __profcxx_list_rewind(this); 00212 return reverse_iterator(end()); 00213 } 00214 00215 const_reverse_iterator 00216 rbegin() const _GLIBCXX_NOEXCEPT 00217 { 00218 __profcxx_list_rewind(this); 00219 return const_reverse_iterator(end()); 00220 } 00221 00222 reverse_iterator 00223 rend() _GLIBCXX_NOEXCEPT 00224 { return reverse_iterator(begin()); } 00225 00226 const_reverse_iterator 00227 rend() const _GLIBCXX_NOEXCEPT 00228 { return const_reverse_iterator(begin()); } 00229 00230 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00231 const_iterator 00232 cbegin() const noexcept 00233 { return const_iterator(_Base::begin(), this); } 00234 00235 const_iterator 00236 cend() const noexcept 00237 { return const_iterator(_Base::end(), this); } 00238 00239 const_reverse_iterator 00240 crbegin() const noexcept 00241 { return const_reverse_iterator(end()); } 00242 00243 const_reverse_iterator 00244 crend() const noexcept 00245 { return const_reverse_iterator(begin()); } 00246 #endif 00247 00248 // 23.2.2.2 capacity: 00249 using _Base::empty; 00250 using _Base::size; 00251 using _Base::max_size; 00252 00253 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00254 void 00255 resize(size_type __sz) 00256 { _Base::resize(__sz); } 00257 00258 void 00259 resize(size_type __sz, const _Tp& __c) 00260 { _Base::resize(__sz, __c); } 00261 #else 00262 void 00263 resize(size_type __sz, _Tp __c = _Tp()) 00264 { _Base::resize(__sz, __c); } 00265 #endif 00266 00267 // element access: 00268 reference 00269 front() 00270 { return _Base::front(); } 00271 00272 const_reference 00273 front() const 00274 { return _Base::front(); } 00275 00276 reference 00277 back() 00278 { 00279 __profcxx_list_rewind(this); 00280 return _Base::back(); 00281 } 00282 00283 const_reference 00284 back() const 00285 { 00286 __profcxx_list_rewind(this); 00287 return _Base::back(); 00288 } 00289 00290 // 23.2.2.3 modifiers: 00291 void 00292 push_front(const value_type& __x) 00293 { 00294 __profcxx_list_invalid_operator(this); 00295 __profcxx_list_operation(this); 00296 _Base::push_front(__x); 00297 } 00298 00299 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00300 using _Base::emplace_front; 00301 #endif 00302 00303 void 00304 pop_front() 00305 { 00306 __profcxx_list_operation(this); 00307 _Base::pop_front(); 00308 } 00309 00310 using _Base::push_back; 00311 00312 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00313 using _Base::emplace_back; 00314 #endif 00315 00316 void 00317 pop_back() 00318 { 00319 iterator __victim = end(); 00320 --__victim; 00321 _Base::pop_back(); 00322 __profcxx_list_rewind(this); 00323 } 00324 00325 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00326 template<typename... _Args> 00327 iterator 00328 emplace(iterator __position, _Args&&... __args) 00329 { 00330 return iterator(_Base::emplace(__position.base(), 00331 std::forward<_Args>(__args)...)); 00332 } 00333 #endif 00334 00335 iterator 00336 insert(iterator __position, const _Tp& __x) 00337 { 00338 _M_profile_insert(this, __position, size()); 00339 return iterator(_Base::insert(__position.base(), __x), this); 00340 } 00341 00342 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00343 iterator 00344 insert(iterator __position, _Tp&& __x) 00345 { 00346 _M_profile_insert(this, __position, size()); 00347 return iterator(_Base::emplace(__position.base(), std::move(__x)), 00348 this); 00349 } 00350 00351 void 00352 insert(iterator __position, initializer_list<value_type> __l) 00353 { 00354 _M_profile_insert(this, __position, size()); 00355 _Base::insert(__position.base(), __l); 00356 } 00357 #endif 00358 00359 void 00360 insert(iterator __position, size_type __n, const _Tp& __x) 00361 { 00362 _M_profile_insert(this, __position, size()); 00363 _Base::insert(__position.base(), __n, __x); 00364 } 00365 00366 template<class _InputIterator> 00367 void 00368 insert(iterator __position, _InputIterator __first, 00369 _InputIterator __last) 00370 { 00371 _M_profile_insert(this, __position, size()); 00372 _Base::insert(__position.base(), __first, __last); 00373 } 00374 00375 iterator 00376 erase(iterator __position) 00377 { return iterator(_Base::erase(__position.base()), this); } 00378 00379 iterator 00380 erase(iterator __position, iterator __last) 00381 { 00382 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00383 // 151. can't currently clear() empty container 00384 return iterator(_Base::erase(__position.base(), __last.base()), this); 00385 } 00386 00387 void 00388 swap(list& __x) 00389 { _Base::swap(__x); } 00390 00391 void 00392 clear() _GLIBCXX_NOEXCEPT 00393 { _Base::clear(); } 00394 00395 // 23.2.2.4 list operations: 00396 void 00397 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00398 splice(iterator __position, list&& __x) 00399 #else 00400 splice(iterator __position, list& __x) 00401 #endif 00402 { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); } 00403 00404 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00405 void 00406 splice(iterator __position, list& __x) 00407 { this->splice(__position, std::move(__x)); } 00408 #endif 00409 00410 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00411 void 00412 splice(iterator __position, list& __x, iterator __i) 00413 { this->splice(__position, std::move(__x), __i); } 00414 #endif 00415 00416 void 00417 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00418 splice(iterator __position, list&& __x, iterator __i) 00419 #else 00420 splice(iterator __position, list& __x, iterator __i) 00421 #endif 00422 { 00423 // We used to perform the splice_alloc check: not anymore, redundant 00424 // after implementing the relevant bits of N1599. 00425 00426 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00427 _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()), 00428 __i.base()); 00429 } 00430 00431 void 00432 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00433 splice(iterator __position, list&& __x, iterator __first, 00434 iterator __last) 00435 #else 00436 splice(iterator __position, list& __x, iterator __first, 00437 iterator __last) 00438 #endif 00439 { 00440 // We used to perform the splice_alloc check: not anymore, redundant 00441 // after implementing the relevant bits of N1599. 00442 00443 _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()), 00444 __first.base(), __last.base()); 00445 } 00446 00447 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00448 void 00449 splice(iterator __position, list& __x, iterator __first, iterator __last) 00450 { this->splice(__position, std::move(__x), __first, __last); } 00451 #endif 00452 00453 void 00454 remove(const _Tp& __value) 00455 { 00456 for (iterator __x = begin(); __x != end(); ) 00457 { 00458 if (*__x == __value) 00459 __x = erase(__x); 00460 else 00461 ++__x; 00462 } 00463 } 00464 00465 template<class _Predicate> 00466 void 00467 remove_if(_Predicate __pred) 00468 { 00469 for (iterator __x = begin(); __x != end(); ) 00470 { 00471 __profcxx_list_operation(this); 00472 if (__pred(*__x)) 00473 __x = erase(__x); 00474 else 00475 ++__x; 00476 } 00477 } 00478 00479 void 00480 unique() 00481 { 00482 iterator __first = begin(); 00483 iterator __last = end(); 00484 if (__first == __last) 00485 return; 00486 iterator __next = __first; 00487 while (++__next != __last) 00488 { 00489 __profcxx_list_operation(this); 00490 if (*__first == *__next) 00491 erase(__next); 00492 else 00493 __first = __next; 00494 __next = __first; 00495 } 00496 } 00497 00498 template<class _BinaryPredicate> 00499 void 00500 unique(_BinaryPredicate __binary_pred) 00501 { 00502 iterator __first = begin(); 00503 iterator __last = end(); 00504 if (__first == __last) 00505 return; 00506 iterator __next = __first; 00507 while (++__next != __last) 00508 { 00509 __profcxx_list_operation(this); 00510 if (__binary_pred(*__first, *__next)) 00511 erase(__next); 00512 else 00513 __first = __next; 00514 __next = __first; 00515 } 00516 } 00517 00518 void 00519 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00520 merge(list&& __x) 00521 #else 00522 merge(list& __x) 00523 #endif 00524 { 00525 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00526 // 300. list::merge() specification incomplete 00527 if (this != &__x) 00528 { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); } 00529 } 00530 00531 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00532 void 00533 merge(list& __x) 00534 { this->merge(std::move(__x)); } 00535 #endif 00536 00537 template<class _Compare> 00538 void 00539 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00540 merge(list&& __x, _Compare __comp) 00541 #else 00542 merge(list& __x, _Compare __comp) 00543 #endif 00544 { 00545 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00546 // 300. list::merge() specification incomplete 00547 if (this != &__x) 00548 { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); } 00549 } 00550 00551 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00552 template<typename _Compare> 00553 void 00554 merge(list& __x, _Compare __comp) 00555 { this->merge(std::move(__x), __comp); } 00556 #endif 00557 00558 void 00559 sort() { _Base::sort(); } 00560 00561 template<typename _StrictWeakOrdering> 00562 void 00563 sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } 00564 00565 using _Base::reverse; 00566 00567 _Base& 00568 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 00569 00570 const _Base& 00571 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 00572 00573 void _M_profile_find() const 00574 { } 00575 00576 void _M_profile_iterate(int __rewind = 0) const 00577 { 00578 __profcxx_list_operation(this); 00579 __profcxx_list_iterate(this); 00580 if (__rewind) 00581 __profcxx_list_rewind(this); 00582 } 00583 00584 private: 00585 size_type _M_profile_insert(void* obj, iterator __pos, size_type __size) 00586 { 00587 size_type __shift = 0; 00588 typename _Base::iterator __it = __pos.base(); 00589 for ( ; __it!=_Base::end(); __it++) 00590 __shift++; 00591 __profcxx_list_rewind(this); 00592 __profcxx_list_operation(this); 00593 __profcxx_list_insert(this, __shift, __size); 00594 } 00595 }; 00596 00597 template<typename _Tp, typename _Alloc> 00598 inline bool 00599 operator==(const list<_Tp, _Alloc>& __lhs, 00600 const list<_Tp, _Alloc>& __rhs) 00601 { return __lhs._M_base() == __rhs._M_base(); } 00602 00603 template<typename _Tp, typename _Alloc> 00604 inline bool 00605 operator!=(const list<_Tp, _Alloc>& __lhs, 00606 const list<_Tp, _Alloc>& __rhs) 00607 { return __lhs._M_base() != __rhs._M_base(); } 00608 00609 template<typename _Tp, typename _Alloc> 00610 inline bool 00611 operator<(const list<_Tp, _Alloc>& __lhs, 00612 const list<_Tp, _Alloc>& __rhs) 00613 { return __lhs._M_base() < __rhs._M_base(); } 00614 00615 template<typename _Tp, typename _Alloc> 00616 inline bool 00617 operator<=(const list<_Tp, _Alloc>& __lhs, 00618 const list<_Tp, _Alloc>& __rhs) 00619 { return __lhs._M_base() <= __rhs._M_base(); } 00620 00621 template<typename _Tp, typename _Alloc> 00622 inline bool 00623 operator>=(const list<_Tp, _Alloc>& __lhs, 00624 const list<_Tp, _Alloc>& __rhs) 00625 { return __lhs._M_base() >= __rhs._M_base(); } 00626 00627 template<typename _Tp, typename _Alloc> 00628 inline bool 00629 operator>(const list<_Tp, _Alloc>& __lhs, 00630 const list<_Tp, _Alloc>& __rhs) 00631 { return __lhs._M_base() > __rhs._M_base(); } 00632 00633 template<typename _Tp, typename _Alloc> 00634 inline void 00635 swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) 00636 { __lhs.swap(__rhs); } 00637 00638 } // namespace __profile 00639 } // namespace std 00640 00641 #endif