libstdc++
|
00001 // Profiling vector implementation -*- C++ -*- 00002 00003 // Copyright (C) 2009-2013 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 #if __cplusplus >= 201103L 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 #if __cplusplus >= 201103L 00086 explicit 00087 vector(size_type __n, const _Allocator& __a = _Allocator()) 00088 : _Base(__n, __a) 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 #if __cplusplus >= 201103L 00113 template<typename _InputIterator, 00114 typename = std::_RequireInputIter<_InputIterator>> 00115 #else 00116 template<typename _InputIterator> 00117 #endif 00118 vector(_InputIterator __first, _InputIterator __last, 00119 const _Allocator& __a = _Allocator()) 00120 : _Base(__first, __last, __a) 00121 { 00122 __profcxx_vector_construct(this, this->capacity()); 00123 __profcxx_vector_construct2(this); 00124 } 00125 00126 vector(const vector& __x) 00127 : _Base(__x) 00128 { 00129 __profcxx_vector_construct(this, this->capacity()); 00130 __profcxx_vector_construct2(this); 00131 } 00132 00133 /// Construction from a release-mode vector 00134 vector(const _Base& __x) 00135 : _Base(__x) 00136 { 00137 __profcxx_vector_construct(this, this->capacity()); 00138 __profcxx_vector_construct2(this); 00139 } 00140 00141 #if __cplusplus >= 201103L 00142 vector(vector&& __x) noexcept 00143 : _Base(std::move(__x)) 00144 { 00145 __profcxx_vector_construct(this, this->capacity()); 00146 __profcxx_vector_construct2(this); 00147 } 00148 00149 vector(const _Base& __x, const _Allocator& __a) 00150 : _Base(__x, __a) 00151 { 00152 __profcxx_vector_construct(this, this->capacity()); 00153 __profcxx_vector_construct2(this); 00154 } 00155 00156 vector(vector&& __x, const _Allocator& __a) noexcept 00157 : _Base(std::move(__x), __a) 00158 { 00159 __profcxx_vector_construct(this, this->capacity()); 00160 __profcxx_vector_construct2(this); 00161 } 00162 00163 vector(initializer_list<value_type> __l, 00164 const allocator_type& __a = allocator_type()) 00165 : _Base(__l, __a) { } 00166 #endif 00167 00168 ~vector() _GLIBCXX_NOEXCEPT 00169 { 00170 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00171 __profcxx_vector_destruct2(this); 00172 } 00173 00174 vector& 00175 operator=(const vector& __x) 00176 { 00177 static_cast<_Base&>(*this) = __x; 00178 return *this; 00179 } 00180 00181 #if __cplusplus >= 201103L 00182 vector& 00183 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 00184 { 00185 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00186 __profcxx_vector_destruct2(this); 00187 static_cast<_Base&>(*this) = std::move(__x); 00188 return *this; 00189 } 00190 00191 vector& 00192 operator=(initializer_list<value_type> __l) 00193 { 00194 static_cast<_Base&>(*this) = __l; 00195 return *this; 00196 } 00197 #endif 00198 00199 using _Base::assign; 00200 using _Base::get_allocator; 00201 00202 00203 // iterators: 00204 iterator 00205 begin() _GLIBCXX_NOEXCEPT 00206 { return iterator(_Base::begin(), this); } 00207 00208 const_iterator 00209 begin() const _GLIBCXX_NOEXCEPT 00210 { return const_iterator(_Base::begin(), this); } 00211 00212 iterator 00213 end() _GLIBCXX_NOEXCEPT 00214 { return iterator(_Base::end(), this); } 00215 00216 const_iterator 00217 end() const _GLIBCXX_NOEXCEPT 00218 { return const_iterator(_Base::end(), this); } 00219 00220 reverse_iterator 00221 rbegin() _GLIBCXX_NOEXCEPT 00222 { return reverse_iterator(end()); } 00223 00224 const_reverse_iterator 00225 rbegin() const _GLIBCXX_NOEXCEPT 00226 { return const_reverse_iterator(end()); } 00227 00228 reverse_iterator 00229 rend() _GLIBCXX_NOEXCEPT 00230 { return reverse_iterator(begin()); } 00231 00232 const_reverse_iterator 00233 rend() const _GLIBCXX_NOEXCEPT 00234 { return const_reverse_iterator(begin()); } 00235 00236 #if __cplusplus >= 201103L 00237 const_iterator 00238 cbegin() const noexcept 00239 { return const_iterator(_Base::begin(), this); } 00240 00241 const_iterator 00242 cend() const noexcept 00243 { return const_iterator(_Base::end(), this); } 00244 00245 const_reverse_iterator 00246 crbegin() const noexcept 00247 { return const_reverse_iterator(end()); } 00248 00249 const_reverse_iterator 00250 crend() const noexcept 00251 { return const_reverse_iterator(begin()); } 00252 #endif 00253 00254 // 23.2.4.2 capacity: 00255 using _Base::size; 00256 using _Base::max_size; 00257 00258 #if __cplusplus >= 201103L 00259 void 00260 resize(size_type __sz) 00261 { 00262 __profcxx_vector_invalid_operator(this); 00263 _M_profile_resize(this, this->capacity(), __sz); 00264 _Base::resize(__sz); 00265 } 00266 00267 void 00268 resize(size_type __sz, const _Tp& __c) 00269 { 00270 __profcxx_vector_invalid_operator(this); 00271 _M_profile_resize(this, this->capacity(), __sz); 00272 _Base::resize(__sz, __c); 00273 } 00274 #else 00275 void 00276 resize(size_type __sz, _Tp __c = _Tp()) 00277 { 00278 __profcxx_vector_invalid_operator(this); 00279 _M_profile_resize(this, this->capacity(), __sz); 00280 _Base::resize(__sz, __c); 00281 } 00282 #endif 00283 00284 #if __cplusplus >= 201103L 00285 using _Base::shrink_to_fit; 00286 #endif 00287 00288 using _Base::empty; 00289 00290 // element access: 00291 reference 00292 operator[](size_type __n) 00293 { 00294 __profcxx_vector_invalid_operator(this); 00295 return _M_base()[__n]; 00296 } 00297 const_reference 00298 operator[](size_type __n) const 00299 { 00300 __profcxx_vector_invalid_operator(this); 00301 return _M_base()[__n]; 00302 } 00303 00304 using _Base::at; 00305 00306 reference 00307 front() 00308 { 00309 return _Base::front(); 00310 } 00311 00312 const_reference 00313 front() const 00314 { 00315 return _Base::front(); 00316 } 00317 00318 reference 00319 back() 00320 { 00321 return _Base::back(); 00322 } 00323 00324 const_reference 00325 back() const 00326 { 00327 return _Base::back(); 00328 } 00329 00330 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00331 // DR 464. Suggestion for new member functions in standard containers. 00332 using _Base::data; 00333 00334 // 23.2.4.3 modifiers: 00335 void 00336 push_back(const _Tp& __x) 00337 { 00338 size_type __old_size = this->capacity(); 00339 _Base::push_back(__x); 00340 _M_profile_resize(this, __old_size, this->capacity()); 00341 } 00342 00343 #if __cplusplus >= 201103L 00344 void 00345 push_back(_Tp&& __x) 00346 { 00347 size_type __old_size = this->capacity(); 00348 _Base::push_back(std::move(__x)); 00349 _M_profile_resize(this, __old_size, this->capacity()); 00350 } 00351 00352 #endif 00353 00354 iterator 00355 insert(iterator __position, const _Tp& __x) 00356 { 00357 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00358 this->size()); 00359 size_type __old_size = this->capacity(); 00360 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 00361 _M_profile_resize(this, __old_size, this->capacity()); 00362 return iterator(__res, this); 00363 } 00364 00365 #if __cplusplus >= 201103L 00366 iterator 00367 insert(iterator __position, _Tp&& __x) 00368 { 00369 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00370 this->size()); 00371 size_type __old_size = this->capacity(); 00372 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 00373 _M_profile_resize(this, __old_size, this->capacity()); 00374 return iterator(__res, this); 00375 } 00376 00377 void 00378 insert(iterator __position, initializer_list<value_type> __l) 00379 { this->insert(__position, __l.begin(), __l.end()); } 00380 #endif 00381 00382 #if __cplusplus >= 201103L 00383 void 00384 swap(vector&& __x) 00385 { 00386 _Base::swap(__x); 00387 } 00388 #endif 00389 00390 void 00391 swap(vector& __x) 00392 #if __cplusplus >= 201103L 00393 noexcept(_Alloc_traits::_S_nothrow_swap()) 00394 #endif 00395 { 00396 _Base::swap(__x); 00397 } 00398 00399 void 00400 insert(iterator __position, size_type __n, const _Tp& __x) 00401 { 00402 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00403 this->size()); 00404 size_type __old_size = this->capacity(); 00405 _Base::insert(__position, __n, __x); 00406 _M_profile_resize(this, __old_size, this->capacity()); 00407 } 00408 00409 #if __cplusplus >= 201103L 00410 template<typename _InputIterator, 00411 typename = std::_RequireInputIter<_InputIterator>> 00412 #else 00413 template<typename _InputIterator> 00414 #endif 00415 void 00416 insert(iterator __position, 00417 _InputIterator __first, _InputIterator __last) 00418 { 00419 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 00420 this->size()); 00421 size_type __old_size = this->capacity(); 00422 _Base::insert(__position, __first, __last); 00423 _M_profile_resize(this, __old_size, this->capacity()); 00424 } 00425 00426 00427 iterator 00428 erase(iterator __position) 00429 { 00430 typename _Base::iterator __res = _Base::erase(__position.base()); 00431 return iterator(__res, this); 00432 } 00433 00434 iterator 00435 erase(iterator __first, iterator __last) 00436 { 00437 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00438 // 151. can't currently clear() empty container 00439 typename _Base::iterator __res = _Base::erase(__first.base(), 00440 __last.base()); 00441 return iterator(__res, this); 00442 } 00443 00444 void 00445 clear() _GLIBCXX_NOEXCEPT 00446 { 00447 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00448 __profcxx_vector_destruct2(this); 00449 _Base::clear(); 00450 } 00451 00452 inline void _M_profile_find() const 00453 { 00454 __profcxx_vector_find(this, size()); 00455 } 00456 00457 inline void _M_profile_iterate(int __rewind = 0) const 00458 { 00459 __profcxx_vector_iterate(this); 00460 } 00461 00462 private: 00463 void _M_profile_resize(void* obj, size_type __old_size, 00464 size_type __new_size) 00465 { 00466 if (__old_size < __new_size) { 00467 __profcxx_vector_resize(this, this->size(), __new_size); 00468 __profcxx_vector_resize2(this, this->size(), __new_size); 00469 } 00470 } 00471 }; 00472 00473 template<typename _Tp, typename _Alloc> 00474 inline bool 00475 operator==(const vector<_Tp, _Alloc>& __lhs, 00476 const vector<_Tp, _Alloc>& __rhs) 00477 { return __lhs._M_base() == __rhs._M_base(); } 00478 00479 template<typename _Tp, typename _Alloc> 00480 inline bool 00481 operator!=(const vector<_Tp, _Alloc>& __lhs, 00482 const vector<_Tp, _Alloc>& __rhs) 00483 { return __lhs._M_base() != __rhs._M_base(); } 00484 00485 template<typename _Tp, typename _Alloc> 00486 inline bool 00487 operator<(const vector<_Tp, _Alloc>& __lhs, 00488 const vector<_Tp, _Alloc>& __rhs) 00489 { return __lhs._M_base() < __rhs._M_base(); } 00490 00491 template<typename _Tp, typename _Alloc> 00492 inline bool 00493 operator<=(const vector<_Tp, _Alloc>& __lhs, 00494 const vector<_Tp, _Alloc>& __rhs) 00495 { return __lhs._M_base() <= __rhs._M_base(); } 00496 00497 template<typename _Tp, typename _Alloc> 00498 inline bool 00499 operator>=(const vector<_Tp, _Alloc>& __lhs, 00500 const vector<_Tp, _Alloc>& __rhs) 00501 { return __lhs._M_base() >= __rhs._M_base(); } 00502 00503 template<typename _Tp, typename _Alloc> 00504 inline bool 00505 operator>(const vector<_Tp, _Alloc>& __lhs, 00506 const vector<_Tp, _Alloc>& __rhs) 00507 { return __lhs._M_base() > __rhs._M_base(); } 00508 00509 template<typename _Tp, typename _Alloc> 00510 inline void 00511 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 00512 { __lhs.swap(__rhs); } 00513 00514 #if __cplusplus >= 201103L 00515 template<typename _Tp, typename _Alloc> 00516 inline void 00517 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 00518 { __lhs.swap(__rhs); } 00519 00520 template<typename _Tp, typename _Alloc> 00521 inline void 00522 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 00523 { __lhs.swap(__rhs); } 00524 #endif 00525 00526 } // namespace __profile 00527 00528 #if __cplusplus >= 201103L 00529 // DR 1182. 00530 /// std::hash specialization for vector<bool>. 00531 template<typename _Alloc> 00532 struct hash<__profile::vector<bool, _Alloc>> 00533 : public __hash_base<size_t, __profile::vector<bool, _Alloc>> 00534 { 00535 size_t 00536 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept 00537 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 00538 (__b._M_base()); } 00539 }; 00540 #endif 00541 00542 } // namespace std 00543 00544 #endif