libstdc++
|
00001 // Profiling vector 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 along 00021 // with this library; see the file COPYING3. If not see 00022 // <http://www.gnu.org/licenses/>. 00023 00024 /** @file profile/vector 00025 * This file is a GNU profile extension to the Standard C++ Library. 00026 */ 00027 00028 #ifndef _GLIBCXX_PROFILE_VECTOR 00029 #define _GLIBCXX_PROFILE_VECTOR 1 00030 00031 #include <vector> 00032 #include <utility> 00033 #include <profile/base.h> 00034 #include <profile/iterator_tracker.h> 00035 00036 namespace std _GLIBCXX_VISIBILITY(default) 00037 { 00038 namespace __profile 00039 { 00040 template<typename _Tp, 00041 typename _Allocator = std::allocator<_Tp> > 00042 class vector 00043 : public _GLIBCXX_STD_C::vector<_Tp, _Allocator> 00044 { 00045 typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; 00046 00047 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00048 typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; 00049 #endif 00050 00051 public: 00052 typedef typename _Base::reference reference; 00053 typedef typename _Base::const_reference const_reference; 00054 00055 typedef __iterator_tracker<typename _Base::iterator, vector> 00056 iterator; 00057 typedef __iterator_tracker<typename _Base::const_iterator, vector> 00058 const_iterator; 00059 00060 typedef typename _Base::size_type size_type; 00061 typedef typename _Base::difference_type difference_type; 00062 00063 typedef _Tp value_type; 00064 typedef _Allocator allocator_type; 00065 typedef typename _Base::pointer pointer; 00066 typedef typename _Base::const_pointer const_pointer; 00067 typedef std::reverse_iterator<iterator> reverse_iterator; 00068 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00069 00070 _Base& 00071 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 00072 00073 const _Base& 00074 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 00075 00076 // 23.2.4.1 construct/copy/destroy: 00077 explicit 00078 vector(const _Allocator& __a = _Allocator()) 00079 : _Base(__a) 00080 { 00081 __profcxx_vector_construct(this, this->capacity()); 00082 __profcxx_vector_construct2(this); 00083 } 00084 00085 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00086 explicit 00087 vector(size_type __n) 00088 : _Base(__n) 00089 { 00090 __profcxx_vector_construct(this, this->capacity()); 00091 __profcxx_vector_construct2(this); 00092 } 00093 00094 vector(size_type __n, const _Tp& __value, 00095 const _Allocator& __a = _Allocator()) 00096 : _Base(__n, __value, __a) 00097 { 00098 __profcxx_vector_construct(this, this->capacity()); 00099 __profcxx_vector_construct2(this); 00100 } 00101 #else 00102 explicit 00103 vector(size_type __n, const _Tp& __value = _Tp(), 00104 const _Allocator& __a = _Allocator()) 00105 : _Base(__n, __value, __a) 00106 { 00107 __profcxx_vector_construct(this, this->capacity()); 00108 __profcxx_vector_construct2(this); 00109 } 00110 #endif 00111 00112 template<class _InputIterator> 00113 vector(_InputIterator __first, _InputIterator __last, 00114 const _Allocator& __a = _Allocator()) 00115 : _Base(__first, __last, __a) 00116 { 00117 __profcxx_vector_construct(this, this->capacity()); 00118 __profcxx_vector_construct2(this); 00119 } 00120 00121 vector(const vector& __x) 00122 : _Base(__x) 00123 { 00124 __profcxx_vector_construct(this, this->capacity()); 00125 __profcxx_vector_construct2(this); 00126 } 00127 00128 /// Construction from a release-mode vector 00129 vector(const _Base& __x) 00130 : _Base(__x) 00131 { 00132 __profcxx_vector_construct(this, this->capacity()); 00133 __profcxx_vector_construct2(this); 00134 } 00135 00136 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00137 vector(vector&& __x) noexcept 00138 : _Base(std::move(__x)) 00139 { 00140 __profcxx_vector_construct(this, this->capacity()); 00141 __profcxx_vector_construct2(this); 00142 } 00143 00144 vector(const _Base& __x, const _Allocator& __a) 00145 : _Base(__x) 00146 { 00147 __profcxx_vector_construct(this, this->capacity()); 00148 __profcxx_vector_construct2(this); 00149 } 00150 00151 vector(vector&& __x, const _Allocator& __a) noexcept 00152 : _Base(std::move(__x), __a) 00153 { 00154 __profcxx_vector_construct(this, this->capacity()); 00155 __profcxx_vector_construct2(this); 00156 } 00157 00158 vector(initializer_list<value_type> __l, 00159 const allocator_type& __a = allocator_type()) 00160 : _Base(__l, __a) { } 00161 #endif 00162 00163 ~vector() _GLIBCXX_NOEXCEPT 00164 { 00165 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00166 __profcxx_vector_destruct2(this); 00167 } 00168 00169 vector& 00170 operator=(const vector& __x) 00171 { 00172 static_cast<_Base&>(*this) = __x; 00173 return *this; 00174 } 00175 00176 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00177 vector& 00178 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 00179 { 00180 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00181 __profcxx_vector_destruct2(this); 00182 static_cast<_Base&>(*this) = std::move(__x); 00183 return *this; 00184 } 00185 00186 vector& 00187 operator=(initializer_list<value_type> __l) 00188 { 00189 static_cast<_Base&>(*this) = __l; 00190 return *this; 00191 } 00192 #endif 00193 00194 using _Base::assign; 00195 using _Base::get_allocator; 00196 00197 00198 // iterators: 00199 iterator 00200 begin() _GLIBCXX_NOEXCEPT 00201 { return iterator(_Base::begin(), this); } 00202 00203 const_iterator 00204 begin() const _GLIBCXX_NOEXCEPT 00205 { return const_iterator(_Base::begin(), this); } 00206 00207 iterator 00208 end() _GLIBCXX_NOEXCEPT 00209 { return iterator(_Base::end(), this); } 00210 00211 const_iterator 00212 end() const _GLIBCXX_NOEXCEPT 00213 { return const_iterator(_Base::end(), this); } 00214 00215 reverse_iterator 00216 rbegin() _GLIBCXX_NOEXCEPT 00217 { return reverse_iterator(end()); } 00218 00219 const_reverse_iterator 00220 rbegin() const _GLIBCXX_NOEXCEPT 00221 { return const_reverse_iterator(end()); } 00222 00223 reverse_iterator 00224 rend() _GLIBCXX_NOEXCEPT 00225 { return reverse_iterator(begin()); } 00226 00227 const_reverse_iterator 00228 rend() const _GLIBCXX_NOEXCEPT 00229 { return const_reverse_iterator(begin()); } 00230 00231 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00232 const_iterator 00233 cbegin() const noexcept 00234 { return const_iterator(_Base::begin(), this); } 00235 00236 const_iterator 00237 cend() const noexcept 00238 { return const_iterator(_Base::end(), this); } 00239 00240 const_reverse_iterator 00241 crbegin() const noexcept 00242 { return const_reverse_iterator(end()); } 00243 00244 const_reverse_iterator 00245 crend() const noexcept 00246 { return const_reverse_iterator(begin()); } 00247 #endif 00248 00249 // 23.2.4.2 capacity: 00250 using _Base::size; 00251 using _Base::max_size; 00252 00253 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00254 void 00255 resize(size_type __sz) 00256 { 00257 __profcxx_vector_invalid_operator(this); 00258 _M_profile_resize(this, this->capacity(), __sz); 00259 _Base::resize(__sz); 00260 } 00261 00262 void 00263 resize(size_type __sz, const _Tp& __c) 00264 { 00265 __profcxx_vector_invalid_operator(this); 00266 _M_profile_resize(this, this->capacity(), __sz); 00267 _Base::resize(__sz, __c); 00268 } 00269 #else 00270 void 00271 resize(size_type __sz, _Tp __c = _Tp()) 00272 { 00273 __profcxx_vector_invalid_operator(this); 00274 _M_profile_resize(this, this->capacity(), __sz); 00275 _Base::resize(__sz, __c); 00276 } 00277 #endif 00278 00279 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00280 using _Base::shrink_to_fit; 00281 #endif 00282 00283 using _Base::empty; 00284 00285 // element access: 00286 reference 00287 operator[](size_type __n) 00288 { 00289 __profcxx_vector_invalid_operator(this); 00290 return _M_base()[__n]; 00291 } 00292 const_reference 00293 operator[](size_type __n) const 00294 { 00295 __profcxx_vector_invalid_operator(this); 00296 return _M_base()[__n]; 00297 } 00298 00299 using _Base::at; 00300 00301 reference 00302 front() 00303 { 00304 return _Base::front(); 00305 } 00306 00307 const_reference 00308 front() const 00309 { 00310 return _Base::front(); 00311 } 00312 00313 reference 00314 back() 00315 { 00316 return _Base::back(); 00317 } 00318 00319 const_reference 00320 back() const 00321 { 00322 return _Base::back(); 00323 } 00324 00325 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00326 // DR 464. Suggestion for new member functions in standard containers. 00327 using _Base::data; 00328 00329 // 23.2.4.3 modifiers: 00330 void 00331 push_back(const _Tp& __x) 00332 { 00333 size_type __old_size = this->capacity(); 00334 _Base::push_back(__x); 00335 _M_profile_resize(this, __old_size, this->capacity()); 00336 } 00337 00338 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00339 void 00340 push_back(_Tp&& __x) 00341 { 00342 size_type __old_size = this->capacity(); 00343 _Base::push_back(std::move(__x)); 00344 _M_profile_resize(this, __old_size, this->capacity()); 00345 } 00346 00347 #endif 00348 00349 iterator 00350 insert(iterator __position, const _Tp& __x) 00351 { 00352 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00353 this->size()); 00354 size_type __old_size = this->capacity(); 00355 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 00356 _M_profile_resize(this, __old_size, this->capacity()); 00357 return iterator(__res, this); 00358 } 00359 00360 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00361 iterator 00362 insert(iterator __position, _Tp&& __x) 00363 { 00364 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00365 this->size()); 00366 size_type __old_size = this->capacity(); 00367 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 00368 _M_profile_resize(this, __old_size, this->capacity()); 00369 return iterator(__res, this); 00370 } 00371 00372 void 00373 insert(iterator __position, initializer_list<value_type> __l) 00374 { this->insert(__position, __l.begin(), __l.end()); } 00375 #endif 00376 00377 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00378 void 00379 swap(vector&& __x) 00380 { 00381 _Base::swap(__x); 00382 } 00383 #endif 00384 00385 void 00386 swap(vector& __x) 00387 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00388 noexcept(_Alloc_traits::_S_nothrow_swap()) 00389 #endif 00390 { 00391 _Base::swap(__x); 00392 } 00393 00394 void 00395 insert(iterator __position, size_type __n, const _Tp& __x) 00396 { 00397 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00398 this->size()); 00399 size_type __old_size = this->capacity(); 00400 _Base::insert(__position, __n, __x); 00401 _M_profile_resize(this, __old_size, this->capacity()); 00402 } 00403 00404 template<class _InputIterator> 00405 void 00406 insert(iterator __position, 00407 _InputIterator __first, _InputIterator __last) 00408 { 00409 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 00410 this->size()); 00411 size_type __old_size = this->capacity(); 00412 _Base::insert(__position, __first, __last); 00413 _M_profile_resize(this, __old_size, this->capacity()); 00414 } 00415 00416 00417 iterator 00418 erase(iterator __position) 00419 { 00420 typename _Base::iterator __res = _Base::erase(__position.base()); 00421 return iterator(__res, this); 00422 } 00423 00424 iterator 00425 erase(iterator __first, iterator __last) 00426 { 00427 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00428 // 151. can't currently clear() empty container 00429 typename _Base::iterator __res = _Base::erase(__first.base(), 00430 __last.base()); 00431 return iterator(__res, this); 00432 } 00433 00434 void 00435 clear() _GLIBCXX_NOEXCEPT 00436 { 00437 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00438 __profcxx_vector_destruct2(this); 00439 _Base::clear(); 00440 } 00441 00442 inline void _M_profile_find() const 00443 { 00444 __profcxx_vector_find(this, size()); 00445 } 00446 00447 inline void _M_profile_iterate(int __rewind = 0) const 00448 { 00449 __profcxx_vector_iterate(this); 00450 } 00451 00452 private: 00453 void _M_profile_resize(void* obj, size_type __old_size, 00454 size_type __new_size) 00455 { 00456 if (__old_size < __new_size) { 00457 __profcxx_vector_resize(this, this->size(), __new_size); 00458 __profcxx_vector_resize2(this, this->size(), __new_size); 00459 } 00460 } 00461 }; 00462 00463 template<typename _Tp, typename _Alloc> 00464 inline bool 00465 operator==(const vector<_Tp, _Alloc>& __lhs, 00466 const vector<_Tp, _Alloc>& __rhs) 00467 { return __lhs._M_base() == __rhs._M_base(); } 00468 00469 template<typename _Tp, typename _Alloc> 00470 inline bool 00471 operator!=(const vector<_Tp, _Alloc>& __lhs, 00472 const vector<_Tp, _Alloc>& __rhs) 00473 { return __lhs._M_base() != __rhs._M_base(); } 00474 00475 template<typename _Tp, typename _Alloc> 00476 inline bool 00477 operator<(const vector<_Tp, _Alloc>& __lhs, 00478 const vector<_Tp, _Alloc>& __rhs) 00479 { return __lhs._M_base() < __rhs._M_base(); } 00480 00481 template<typename _Tp, typename _Alloc> 00482 inline bool 00483 operator<=(const vector<_Tp, _Alloc>& __lhs, 00484 const vector<_Tp, _Alloc>& __rhs) 00485 { return __lhs._M_base() <= __rhs._M_base(); } 00486 00487 template<typename _Tp, typename _Alloc> 00488 inline bool 00489 operator>=(const vector<_Tp, _Alloc>& __lhs, 00490 const vector<_Tp, _Alloc>& __rhs) 00491 { return __lhs._M_base() >= __rhs._M_base(); } 00492 00493 template<typename _Tp, typename _Alloc> 00494 inline bool 00495 operator>(const vector<_Tp, _Alloc>& __lhs, 00496 const vector<_Tp, _Alloc>& __rhs) 00497 { return __lhs._M_base() > __rhs._M_base(); } 00498 00499 template<typename _Tp, typename _Alloc> 00500 inline void 00501 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 00502 { __lhs.swap(__rhs); } 00503 00504 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00505 template<typename _Tp, typename _Alloc> 00506 inline void 00507 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 00508 { __lhs.swap(__rhs); } 00509 00510 template<typename _Tp, typename _Alloc> 00511 inline void 00512 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 00513 { __lhs.swap(__rhs); } 00514 #endif 00515 00516 } // namespace __profile 00517 00518 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00519 // DR 1182. 00520 /// std::hash specialization for vector<bool>. 00521 template<typename _Alloc> 00522 struct hash<__profile::vector<bool, _Alloc>> 00523 : public __hash_base<size_t, __profile::vector<bool, _Alloc>> 00524 { 00525 size_t 00526 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept 00527 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 00528 (__b._M_base()); } 00529 }; 00530 #endif 00531 00532 } // namespace std 00533 00534 #endif