1// Profiling vector implementation -*- C++ -*- 2 3// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10// 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License along 21// with this library; see the file COPYING3. If not see 22// <http://www.gnu.org/licenses/>. 23 24/** @file profile/vector 25 * This file is a GNU profile extension to the Standard C++ Library. 26 */ 27 28#ifndef _GLIBCXX_PROFILE_VECTOR 29#define _GLIBCXX_PROFILE_VECTOR 1 30 31#include <vector> 32#include <utility> 33#include <profile/base.h> 34#include <profile/iterator_tracker.h> 35 36namespace std _GLIBCXX_VISIBILITY(default) 37{ 38namespace __profile 39{ 40 template<typename _Tp, 41 typename _Allocator = std::allocator<_Tp> > 42 class vector 43 : public _GLIBCXX_STD_C::vector<_Tp, _Allocator> 44 { 45 typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; 46 47#ifdef __GXX_EXPERIMENTAL_CXX0X__ 48 typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; 49#endif 50 51 public: 52 typedef typename _Base::reference reference; 53 typedef typename _Base::const_reference const_reference; 54 55 typedef __iterator_tracker<typename _Base::iterator, vector> 56 iterator; 57 typedef __iterator_tracker<typename _Base::const_iterator, vector> 58 const_iterator; 59 60 typedef typename _Base::size_type size_type; 61 typedef typename _Base::difference_type difference_type; 62 63 typedef _Tp value_type; 64 typedef _Allocator allocator_type; 65 typedef typename _Base::pointer pointer; 66 typedef typename _Base::const_pointer const_pointer; 67 typedef std::reverse_iterator<iterator> reverse_iterator; 68 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 69 70 _Base& 71 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 72 73 const _Base& 74 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 75 76 // 23.2.4.1 construct/copy/destroy: 77 explicit 78 vector(const _Allocator& __a = _Allocator()) 79 : _Base(__a) 80 { 81 __profcxx_vector_construct(this, this->capacity()); 82 __profcxx_vector_construct2(this); 83 } 84 85#ifdef __GXX_EXPERIMENTAL_CXX0X__ 86 explicit 87 vector(size_type __n) 88 : _Base(__n) 89 { 90 __profcxx_vector_construct(this, this->capacity()); 91 __profcxx_vector_construct2(this); 92 } 93 94 vector(size_type __n, const _Tp& __value, 95 const _Allocator& __a = _Allocator()) 96 : _Base(__n, __value, __a) 97 { 98 __profcxx_vector_construct(this, this->capacity()); 99 __profcxx_vector_construct2(this); 100 } 101#else 102 explicit 103 vector(size_type __n, const _Tp& __value = _Tp(), 104 const _Allocator& __a = _Allocator()) 105 : _Base(__n, __value, __a) 106 { 107 __profcxx_vector_construct(this, this->capacity()); 108 __profcxx_vector_construct2(this); 109 } 110#endif 111 112 template<class _InputIterator> 113 vector(_InputIterator __first, _InputIterator __last, 114 const _Allocator& __a = _Allocator()) 115 : _Base(__first, __last, __a) 116 { 117 __profcxx_vector_construct(this, this->capacity()); 118 __profcxx_vector_construct2(this); 119 } 120 121 vector(const vector& __x) 122 : _Base(__x) 123 { 124 __profcxx_vector_construct(this, this->capacity()); 125 __profcxx_vector_construct2(this); 126 } 127 128 /// Construction from a release-mode vector 129 vector(const _Base& __x) 130 : _Base(__x) 131 { 132 __profcxx_vector_construct(this, this->capacity()); 133 __profcxx_vector_construct2(this); 134 } 135 136#ifdef __GXX_EXPERIMENTAL_CXX0X__ 137 vector(vector&& __x) noexcept 138 : _Base(std::move(__x)) 139 { 140 __profcxx_vector_construct(this, this->capacity()); 141 __profcxx_vector_construct2(this); 142 } 143 144 vector(const _Base& __x, const _Allocator& __a) 145 : _Base(__x) 146 { 147 __profcxx_vector_construct(this, this->capacity()); 148 __profcxx_vector_construct2(this); 149 } 150 151 vector(vector&& __x, const _Allocator& __a) noexcept 152 : _Base(std::move(__x), __a) 153 { 154 __profcxx_vector_construct(this, this->capacity()); 155 __profcxx_vector_construct2(this); 156 } 157 158 vector(initializer_list<value_type> __l, 159 const allocator_type& __a = allocator_type()) 160 : _Base(__l, __a) { } 161#endif 162 163 ~vector() _GLIBCXX_NOEXCEPT 164 { 165 __profcxx_vector_destruct(this, this->capacity(), this->size()); 166 __profcxx_vector_destruct2(this); 167 } 168 169 vector& 170 operator=(const vector& __x) 171 { 172 static_cast<_Base&>(*this) = __x; 173 return *this; 174 } 175 176#ifdef __GXX_EXPERIMENTAL_CXX0X__ 177 vector& 178 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 179 { 180 __profcxx_vector_destruct(this, this->capacity(), this->size()); 181 __profcxx_vector_destruct2(this); 182 static_cast<_Base&>(*this) = std::move(__x); 183 return *this; 184 } 185 186 vector& 187 operator=(initializer_list<value_type> __l) 188 { 189 static_cast<_Base&>(*this) = __l; 190 return *this; 191 } 192#endif 193 194 using _Base::assign; 195 using _Base::get_allocator; 196 197 198 // iterators: 199 iterator 200 begin() _GLIBCXX_NOEXCEPT 201 { return iterator(_Base::begin(), this); } 202 203 const_iterator 204 begin() const _GLIBCXX_NOEXCEPT 205 { return const_iterator(_Base::begin(), this); } 206 207 iterator 208 end() _GLIBCXX_NOEXCEPT 209 { return iterator(_Base::end(), this); } 210 211 const_iterator 212 end() const _GLIBCXX_NOEXCEPT 213 { return const_iterator(_Base::end(), this); } 214 215 reverse_iterator 216 rbegin() _GLIBCXX_NOEXCEPT 217 { return reverse_iterator(end()); } 218 219 const_reverse_iterator 220 rbegin() const _GLIBCXX_NOEXCEPT 221 { return const_reverse_iterator(end()); } 222 223 reverse_iterator 224 rend() _GLIBCXX_NOEXCEPT 225 { return reverse_iterator(begin()); } 226 227 const_reverse_iterator 228 rend() const _GLIBCXX_NOEXCEPT 229 { return const_reverse_iterator(begin()); } 230 231#ifdef __GXX_EXPERIMENTAL_CXX0X__ 232 const_iterator 233 cbegin() const noexcept 234 { return const_iterator(_Base::begin(), this); } 235 236 const_iterator 237 cend() const noexcept 238 { return const_iterator(_Base::end(), this); } 239 240 const_reverse_iterator 241 crbegin() const noexcept 242 { return const_reverse_iterator(end()); } 243 244 const_reverse_iterator 245 crend() const noexcept 246 { return const_reverse_iterator(begin()); } 247#endif 248 249 // 23.2.4.2 capacity: 250 using _Base::size; 251 using _Base::max_size; 252 253#ifdef __GXX_EXPERIMENTAL_CXX0X__ 254 void 255 resize(size_type __sz) 256 { 257 __profcxx_vector_invalid_operator(this); 258 _M_profile_resize(this, this->capacity(), __sz); 259 _Base::resize(__sz); 260 } 261 262 void 263 resize(size_type __sz, const _Tp& __c) 264 { 265 __profcxx_vector_invalid_operator(this); 266 _M_profile_resize(this, this->capacity(), __sz); 267 _Base::resize(__sz, __c); 268 } 269#else 270 void 271 resize(size_type __sz, _Tp __c = _Tp()) 272 { 273 __profcxx_vector_invalid_operator(this); 274 _M_profile_resize(this, this->capacity(), __sz); 275 _Base::resize(__sz, __c); 276 } 277#endif 278 279#ifdef __GXX_EXPERIMENTAL_CXX0X__ 280 using _Base::shrink_to_fit; 281#endif 282 283 using _Base::empty; 284 285 // element access: 286 reference 287 operator[](size_type __n) 288 { 289 __profcxx_vector_invalid_operator(this); 290 return _M_base()[__n]; 291 } 292 const_reference 293 operator[](size_type __n) const 294 { 295 __profcxx_vector_invalid_operator(this); 296 return _M_base()[__n]; 297 } 298 299 using _Base::at; 300 301 reference 302 front() 303 { 304 return _Base::front(); 305 } 306 307 const_reference 308 front() const 309 { 310 return _Base::front(); 311 } 312 313 reference 314 back() 315 { 316 return _Base::back(); 317 } 318 319 const_reference 320 back() const 321 { 322 return _Base::back(); 323 } 324 325 // _GLIBCXX_RESOLVE_LIB_DEFECTS 326 // DR 464. Suggestion for new member functions in standard containers. 327 using _Base::data; 328 329 // 23.2.4.3 modifiers: 330 void 331 push_back(const _Tp& __x) 332 { 333 size_type __old_size = this->capacity(); 334 _Base::push_back(__x); 335 _M_profile_resize(this, __old_size, this->capacity()); 336 } 337 338#ifdef __GXX_EXPERIMENTAL_CXX0X__ 339 void 340 push_back(_Tp&& __x) 341 { 342 size_type __old_size = this->capacity(); 343 _Base::push_back(std::move(__x)); 344 _M_profile_resize(this, __old_size, this->capacity()); 345 } 346 347#endif 348 349 iterator 350 insert(iterator __position, const _Tp& __x) 351 { 352 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 353 this->size()); 354 size_type __old_size = this->capacity(); 355 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 356 _M_profile_resize(this, __old_size, this->capacity()); 357 return iterator(__res, this); 358 } 359 360#ifdef __GXX_EXPERIMENTAL_CXX0X__ 361 iterator 362 insert(iterator __position, _Tp&& __x) 363 { 364 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 365 this->size()); 366 size_type __old_size = this->capacity(); 367 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 368 _M_profile_resize(this, __old_size, this->capacity()); 369 return iterator(__res, this); 370 } 371 372 void 373 insert(iterator __position, initializer_list<value_type> __l) 374 { this->insert(__position, __l.begin(), __l.end()); } 375#endif 376 377#ifdef __GXX_EXPERIMENTAL_CXX0X__ 378 void 379 swap(vector&& __x) 380 { 381 _Base::swap(__x); 382 } 383#endif 384 385 void 386 swap(vector& __x) 387#ifdef __GXX_EXPERIMENTAL_CXX0X__ 388 noexcept(_Alloc_traits::_S_nothrow_swap()) 389#endif 390 { 391 _Base::swap(__x); 392 } 393 394 void 395 insert(iterator __position, size_type __n, const _Tp& __x) 396 { 397 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 398 this->size()); 399 size_type __old_size = this->capacity(); 400 _Base::insert(__position, __n, __x); 401 _M_profile_resize(this, __old_size, this->capacity()); 402 } 403 404 template<class _InputIterator> 405 void 406 insert(iterator __position, 407 _InputIterator __first, _InputIterator __last) 408 { 409 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 410 this->size()); 411 size_type __old_size = this->capacity(); 412 _Base::insert(__position, __first, __last); 413 _M_profile_resize(this, __old_size, this->capacity()); 414 } 415 416 417 iterator 418 erase(iterator __position) 419 { 420 typename _Base::iterator __res = _Base::erase(__position.base()); 421 return iterator(__res, this); 422 } 423 424 iterator 425 erase(iterator __first, iterator __last) 426 { 427 // _GLIBCXX_RESOLVE_LIB_DEFECTS 428 // 151. can't currently clear() empty container 429 typename _Base::iterator __res = _Base::erase(__first.base(), 430 __last.base()); 431 return iterator(__res, this); 432 } 433 434 void 435 clear() _GLIBCXX_NOEXCEPT 436 { 437 __profcxx_vector_destruct(this, this->capacity(), this->size()); 438 __profcxx_vector_destruct2(this); 439 _Base::clear(); 440 } 441 442 inline void _M_profile_find() const 443 { 444 __profcxx_vector_find(this, size()); 445 } 446 447 inline void _M_profile_iterate(int __rewind = 0) const 448 { 449 __profcxx_vector_iterate(this); 450 } 451 452 private: 453 void _M_profile_resize(void* obj, size_type __old_size, 454 size_type __new_size) 455 { 456 if (__old_size < __new_size) { 457 __profcxx_vector_resize(this, this->size(), __new_size); 458 __profcxx_vector_resize2(this, this->size(), __new_size); 459 } 460 } 461 }; 462 463 template<typename _Tp, typename _Alloc> 464 inline bool 465 operator==(const vector<_Tp, _Alloc>& __lhs, 466 const vector<_Tp, _Alloc>& __rhs) 467 { return __lhs._M_base() == __rhs._M_base(); } 468 469 template<typename _Tp, typename _Alloc> 470 inline bool 471 operator!=(const vector<_Tp, _Alloc>& __lhs, 472 const vector<_Tp, _Alloc>& __rhs) 473 { return __lhs._M_base() != __rhs._M_base(); } 474 475 template<typename _Tp, typename _Alloc> 476 inline bool 477 operator<(const vector<_Tp, _Alloc>& __lhs, 478 const vector<_Tp, _Alloc>& __rhs) 479 { return __lhs._M_base() < __rhs._M_base(); } 480 481 template<typename _Tp, typename _Alloc> 482 inline bool 483 operator<=(const vector<_Tp, _Alloc>& __lhs, 484 const vector<_Tp, _Alloc>& __rhs) 485 { return __lhs._M_base() <= __rhs._M_base(); } 486 487 template<typename _Tp, typename _Alloc> 488 inline bool 489 operator>=(const vector<_Tp, _Alloc>& __lhs, 490 const vector<_Tp, _Alloc>& __rhs) 491 { return __lhs._M_base() >= __rhs._M_base(); } 492 493 template<typename _Tp, typename _Alloc> 494 inline bool 495 operator>(const vector<_Tp, _Alloc>& __lhs, 496 const vector<_Tp, _Alloc>& __rhs) 497 { return __lhs._M_base() > __rhs._M_base(); } 498 499 template<typename _Tp, typename _Alloc> 500 inline void 501 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 502 { __lhs.swap(__rhs); } 503 504#ifdef __GXX_EXPERIMENTAL_CXX0X__ 505 template<typename _Tp, typename _Alloc> 506 inline void 507 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 508 { __lhs.swap(__rhs); } 509 510 template<typename _Tp, typename _Alloc> 511 inline void 512 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 513 { __lhs.swap(__rhs); } 514#endif 515 516} // namespace __profile 517 518#ifdef __GXX_EXPERIMENTAL_CXX0X__ 519 // DR 1182. 520 /// std::hash specialization for vector<bool>. 521 template<typename _Alloc> 522 struct hash<__profile::vector<bool, _Alloc>> 523 : public __hash_base<size_t, __profile::vector<bool, _Alloc>> 524 { 525 size_t 526 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept 527 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 528 (__b._M_base()); } 529 }; 530#endif 531 532} // namespace std 533 534#endif 535