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 template<typename... _Args> 00378 iterator 00379 emplace(iterator __position, _Args&&... __args) 00380 { 00381 typename _Base::iterator __res 00382 = _Base::emplace(__position.base(), 00383 std::forward<_Args>(__args)...); 00384 return iterator(__res, this); 00385 } 00386 00387 void 00388 insert(iterator __position, initializer_list<value_type> __l) 00389 { this->insert(__position, __l.begin(), __l.end()); } 00390 #endif 00391 00392 #if __cplusplus >= 201103L 00393 void 00394 swap(vector&& __x) 00395 { 00396 _Base::swap(__x); 00397 } 00398 #endif 00399 00400 void 00401 swap(vector& __x) 00402 #if __cplusplus >= 201103L 00403 noexcept(_Alloc_traits::_S_nothrow_swap()) 00404 #endif 00405 { 00406 _Base::swap(__x); 00407 } 00408 00409 void 00410 insert(iterator __position, size_type __n, const _Tp& __x) 00411 { 00412 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 00413 this->size()); 00414 size_type __old_size = this->capacity(); 00415 _Base::insert(__position, __n, __x); 00416 _M_profile_resize(this, __old_size, this->capacity()); 00417 } 00418 00419 #if __cplusplus >= 201103L 00420 template<typename _InputIterator, 00421 typename = std::_RequireInputIter<_InputIterator>> 00422 #else 00423 template<typename _InputIterator> 00424 #endif 00425 void 00426 insert(iterator __position, 00427 _InputIterator __first, _InputIterator __last) 00428 { 00429 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 00430 this->size()); 00431 size_type __old_size = this->capacity(); 00432 _Base::insert(__position, __first, __last); 00433 _M_profile_resize(this, __old_size, this->capacity()); 00434 } 00435 00436 00437 iterator 00438 erase(iterator __position) 00439 { 00440 typename _Base::iterator __res = _Base::erase(__position.base()); 00441 return iterator(__res, this); 00442 } 00443 00444 iterator 00445 erase(iterator __first, iterator __last) 00446 { 00447 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00448 // 151. can't currently clear() empty container 00449 typename _Base::iterator __res = _Base::erase(__first.base(), 00450 __last.base()); 00451 return iterator(__res, this); 00452 } 00453 00454 void 00455 clear() _GLIBCXX_NOEXCEPT 00456 { 00457 __profcxx_vector_destruct(this, this->capacity(), this->size()); 00458 __profcxx_vector_destruct2(this); 00459 _Base::clear(); 00460 } 00461 00462 inline void _M_profile_find() const 00463 { 00464 __profcxx_vector_find(this, size()); 00465 } 00466 00467 inline void _M_profile_iterate(int __rewind = 0) const 00468 { 00469 __profcxx_vector_iterate(this); 00470 } 00471 00472 private: 00473 void _M_profile_resize(void* obj, size_type __old_size, 00474 size_type __new_size) 00475 { 00476 if (__old_size < __new_size) { 00477 __profcxx_vector_resize(this, this->size(), __new_size); 00478 __profcxx_vector_resize2(this, this->size(), __new_size); 00479 } 00480 } 00481 }; 00482 00483 template<typename _Tp, typename _Alloc> 00484 inline bool 00485 operator==(const vector<_Tp, _Alloc>& __lhs, 00486 const vector<_Tp, _Alloc>& __rhs) 00487 { return __lhs._M_base() == __rhs._M_base(); } 00488 00489 template<typename _Tp, typename _Alloc> 00490 inline bool 00491 operator!=(const vector<_Tp, _Alloc>& __lhs, 00492 const vector<_Tp, _Alloc>& __rhs) 00493 { return __lhs._M_base() != __rhs._M_base(); } 00494 00495 template<typename _Tp, typename _Alloc> 00496 inline bool 00497 operator<(const vector<_Tp, _Alloc>& __lhs, 00498 const vector<_Tp, _Alloc>& __rhs) 00499 { return __lhs._M_base() < __rhs._M_base(); } 00500 00501 template<typename _Tp, typename _Alloc> 00502 inline bool 00503 operator<=(const vector<_Tp, _Alloc>& __lhs, 00504 const vector<_Tp, _Alloc>& __rhs) 00505 { return __lhs._M_base() <= __rhs._M_base(); } 00506 00507 template<typename _Tp, typename _Alloc> 00508 inline bool 00509 operator>=(const vector<_Tp, _Alloc>& __lhs, 00510 const vector<_Tp, _Alloc>& __rhs) 00511 { return __lhs._M_base() >= __rhs._M_base(); } 00512 00513 template<typename _Tp, typename _Alloc> 00514 inline bool 00515 operator>(const vector<_Tp, _Alloc>& __lhs, 00516 const vector<_Tp, _Alloc>& __rhs) 00517 { return __lhs._M_base() > __rhs._M_base(); } 00518 00519 template<typename _Tp, typename _Alloc> 00520 inline void 00521 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 00522 { __lhs.swap(__rhs); } 00523 00524 #if __cplusplus >= 201103L 00525 template<typename _Tp, typename _Alloc> 00526 inline void 00527 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 00528 { __lhs.swap(__rhs); } 00529 00530 template<typename _Tp, typename _Alloc> 00531 inline void 00532 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 00533 { __lhs.swap(__rhs); } 00534 #endif 00535 00536 } // namespace __profile 00537 00538 #if __cplusplus >= 201103L 00539 // DR 1182. 00540 /// std::hash specialization for vector<bool>. 00541 template<typename _Alloc> 00542 struct hash<__profile::vector<bool, _Alloc>> 00543 : public __hash_base<size_t, __profile::vector<bool, _Alloc>> 00544 { 00545 size_t 00546 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept 00547 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 00548 (__b._M_base()); } 00549 }; 00550 #endif 00551 00552 } // namespace std 00553 00554 #endif