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