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