1 // Profiling vector implementation -*- C++ -*- 2 3 // Copyright (C) 2009-2013 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 36 namespace std _GLIBCXX_VISIBILITY(default) 37 { 38 namespace __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 #if __cplusplus >= 201103L 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 #if __cplusplus >= 201103L 86 explicit 87 vector(size_type __n, const _Allocator& __a = _Allocator()) 88 : _Base(__n, __a) 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 #if __cplusplus >= 201103L 113 template<typename _InputIterator, 114 typename = std::_RequireInputIter<_InputIterator>> 115 #else 116 template<typename _InputIterator> 117 #endif 118 vector(_InputIterator __first, _InputIterator __last, 119 const _Allocator& __a = _Allocator()) 120 : _Base(__first, __last, __a) 121 { 122 __profcxx_vector_construct(this, this->capacity()); 123 __profcxx_vector_construct2(this); 124 } 125 126 vector(const vector& __x) 127 : _Base(__x) 128 { 129 __profcxx_vector_construct(this, this->capacity()); 130 __profcxx_vector_construct2(this); 131 } 132 133 /// Construction from a release-mode vector 134 vector(const _Base& __x) 135 : _Base(__x) 136 { 137 __profcxx_vector_construct(this, this->capacity()); 138 __profcxx_vector_construct2(this); 139 } 140 141 #if __cplusplus >= 201103L 142 vector(vector&& __x) noexcept 143 : _Base(std::move(__x)) 144 { 145 __profcxx_vector_construct(this, this->capacity()); 146 __profcxx_vector_construct2(this); 147 } 148 149 vector(const _Base& __x, const _Allocator& __a) 150 : _Base(__x, __a) 151 { 152 __profcxx_vector_construct(this, this->capacity()); 153 __profcxx_vector_construct2(this); 154 } 155 156 vector(vector&& __x, const _Allocator& __a) noexcept 157 : _Base(std::move(__x), __a) 158 { 159 __profcxx_vector_construct(this, this->capacity()); 160 __profcxx_vector_construct2(this); 161 } 162 163 vector(initializer_list<value_type> __l, 164 const allocator_type& __a = allocator_type()) 165 : _Base(__l, __a) { } 166 #endif 167 168 ~vector() _GLIBCXX_NOEXCEPT 169 { 170 __profcxx_vector_destruct(this, this->capacity(), this->size()); 171 __profcxx_vector_destruct2(this); 172 } 173 174 vector& 175 operator=(const vector& __x) 176 { 177 static_cast<_Base&>(*this) = __x; 178 return *this; 179 } 180 181 #if __cplusplus >= 201103L 182 vector& 183 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 184 { 185 __profcxx_vector_destruct(this, this->capacity(), this->size()); 186 __profcxx_vector_destruct2(this); 187 static_cast<_Base&>(*this) = std::move(__x); 188 return *this; 189 } 190 191 vector& 192 operator=(initializer_list<value_type> __l) 193 { 194 static_cast<_Base&>(*this) = __l; 195 return *this; 196 } 197 #endif 198 199 using _Base::assign; 200 using _Base::get_allocator; 201 202 203 // iterators: 204 iterator 205 begin() _GLIBCXX_NOEXCEPT 206 { return iterator(_Base::begin(), this); } 207 208 const_iterator 209 begin() const _GLIBCXX_NOEXCEPT 210 { return const_iterator(_Base::begin(), this); } 211 212 iterator 213 end() _GLIBCXX_NOEXCEPT 214 { return iterator(_Base::end(), this); } 215 216 const_iterator 217 end() const _GLIBCXX_NOEXCEPT 218 { return const_iterator(_Base::end(), this); } 219 220 reverse_iterator 221 rbegin() _GLIBCXX_NOEXCEPT 222 { return reverse_iterator(end()); } 223 224 const_reverse_iterator 225 rbegin() const _GLIBCXX_NOEXCEPT 226 { return const_reverse_iterator(end()); } 227 228 reverse_iterator 229 rend() _GLIBCXX_NOEXCEPT 230 { return reverse_iterator(begin()); } 231 232 const_reverse_iterator 233 rend() const _GLIBCXX_NOEXCEPT 234 { return const_reverse_iterator(begin()); } 235 236 #if __cplusplus >= 201103L 237 const_iterator 238 cbegin() const noexcept 239 { return const_iterator(_Base::begin(), this); } 240 241 const_iterator 242 cend() const noexcept 243 { return const_iterator(_Base::end(), this); } 244 245 const_reverse_iterator 246 crbegin() const noexcept 247 { return const_reverse_iterator(end()); } 248 249 const_reverse_iterator 250 crend() const noexcept 251 { return const_reverse_iterator(begin()); } 252 #endif 253 254 // 23.2.4.2 capacity: 255 using _Base::size; 256 using _Base::max_size; 257 258 #if __cplusplus >= 201103L 259 void 260 resize(size_type __sz) 261 { 262 __profcxx_vector_invalid_operator(this); 263 _M_profile_resize(this, this->capacity(), __sz); 264 _Base::resize(__sz); 265 } 266 267 void 268 resize(size_type __sz, const _Tp& __c) 269 { 270 __profcxx_vector_invalid_operator(this); 271 _M_profile_resize(this, this->capacity(), __sz); 272 _Base::resize(__sz, __c); 273 } 274 #else 275 void 276 resize(size_type __sz, _Tp __c = _Tp()) 277 { 278 __profcxx_vector_invalid_operator(this); 279 _M_profile_resize(this, this->capacity(), __sz); 280 _Base::resize(__sz, __c); 281 } 282 #endif 283 284 #if __cplusplus >= 201103L 285 using _Base::shrink_to_fit; 286 #endif 287 288 using _Base::empty; 289 290 // element access: 291 reference 292 operator[](size_type __n) 293 { 294 __profcxx_vector_invalid_operator(this); 295 return _M_base()[__n]; 296 } 297 const_reference 298 operator[](size_type __n) const 299 { 300 __profcxx_vector_invalid_operator(this); 301 return _M_base()[__n]; 302 } 303 304 using _Base::at; 305 306 reference 307 front() 308 { 309 return _Base::front(); 310 } 311 312 const_reference 313 front() const 314 { 315 return _Base::front(); 316 } 317 318 reference 319 back() 320 { 321 return _Base::back(); 322 } 323 324 const_reference 325 back() const 326 { 327 return _Base::back(); 328 } 329 330 // _GLIBCXX_RESOLVE_LIB_DEFECTS 331 // DR 464. Suggestion for new member functions in standard containers. 332 using _Base::data; 333 334 // 23.2.4.3 modifiers: 335 void 336 push_back(const _Tp& __x) 337 { 338 size_type __old_size = this->capacity(); 339 _Base::push_back(__x); 340 _M_profile_resize(this, __old_size, this->capacity()); 341 } 342 343 #if __cplusplus >= 201103L 344 void 345 push_back(_Tp&& __x) 346 { 347 size_type __old_size = this->capacity(); 348 _Base::push_back(std::move(__x)); 349 _M_profile_resize(this, __old_size, this->capacity()); 350 } 351 352 #endif 353 354 iterator 355 insert(iterator __position, const _Tp& __x) 356 { 357 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 358 this->size()); 359 size_type __old_size = this->capacity(); 360 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 361 _M_profile_resize(this, __old_size, this->capacity()); 362 return iterator(__res, this); 363 } 364 365 #if __cplusplus >= 201103L 366 iterator 367 insert(iterator __position, _Tp&& __x) 368 { 369 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 370 this->size()); 371 size_type __old_size = this->capacity(); 372 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 373 _M_profile_resize(this, __old_size, this->capacity()); 374 return iterator(__res, this); 375 } 376 377 template<typename... _Args> 378 iterator 379 emplace(iterator __position, _Args&&... __args) 380 { 381 typename _Base::iterator __res 382 = _Base::emplace(__position.base(), 383 std::forward<_Args>(__args)...); 384 return iterator(__res, this); 385 } 386 387 void 388 insert(iterator __position, initializer_list<value_type> __l) 389 { this->insert(__position, __l.begin(), __l.end()); } 390 #endif 391 392 #if __cplusplus >= 201103L 393 void 394 swap(vector&& __x) 395 { 396 _Base::swap(__x); 397 } 398 #endif 399 400 void 401 swap(vector& __x) 402 #if __cplusplus >= 201103L 403 noexcept(_Alloc_traits::_S_nothrow_swap()) 404 #endif 405 { 406 _Base::swap(__x); 407 } 408 409 void 410 insert(iterator __position, size_type __n, const _Tp& __x) 411 { 412 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 413 this->size()); 414 size_type __old_size = this->capacity(); 415 _Base::insert(__position, __n, __x); 416 _M_profile_resize(this, __old_size, this->capacity()); 417 } 418 419 #if __cplusplus >= 201103L 420 template<typename _InputIterator, 421 typename = std::_RequireInputIter<_InputIterator>> 422 #else 423 template<typename _InputIterator> 424 #endif 425 void 426 insert(iterator __position, 427 _InputIterator __first, _InputIterator __last) 428 { 429 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 430 this->size()); 431 size_type __old_size = this->capacity(); 432 _Base::insert(__position, __first, __last); 433 _M_profile_resize(this, __old_size, this->capacity()); 434 } 435 436 437 iterator 438 erase(iterator __position) 439 { 440 typename _Base::iterator __res = _Base::erase(__position.base()); 441 return iterator(__res, this); 442 } 443 444 iterator 445 erase(iterator __first, iterator __last) 446 { 447 // _GLIBCXX_RESOLVE_LIB_DEFECTS 448 // 151. can't currently clear() empty container 449 typename _Base::iterator __res = _Base::erase(__first.base(), 450 __last.base()); 451 return iterator(__res, this); 452 } 453 454 void 455 clear() _GLIBCXX_NOEXCEPT 456 { 457 __profcxx_vector_destruct(this, this->capacity(), this->size()); 458 __profcxx_vector_destruct2(this); 459 _Base::clear(); 460 } 461 462 inline void _M_profile_find() const 463 { 464 __profcxx_vector_find(this, size()); 465 } 466 467 inline void _M_profile_iterate(int __rewind = 0) const 468 { 469 __profcxx_vector_iterate(this); 470 } 471 472 private: 473 void _M_profile_resize(void* obj, size_type __old_size, 474 size_type __new_size) 475 { 476 if (__old_size < __new_size) { 477 __profcxx_vector_resize(this, this->size(), __new_size); 478 __profcxx_vector_resize2(this, this->size(), __new_size); 479 } 480 } 481 }; 482 483 template<typename _Tp, typename _Alloc> 484 inline bool 485 operator==(const vector<_Tp, _Alloc>& __lhs, 486 const vector<_Tp, _Alloc>& __rhs) 487 { return __lhs._M_base() == __rhs._M_base(); } 488 489 template<typename _Tp, typename _Alloc> 490 inline bool 491 operator!=(const vector<_Tp, _Alloc>& __lhs, 492 const vector<_Tp, _Alloc>& __rhs) 493 { return __lhs._M_base() != __rhs._M_base(); } 494 495 template<typename _Tp, typename _Alloc> 496 inline bool 497 operator<(const vector<_Tp, _Alloc>& __lhs, 498 const vector<_Tp, _Alloc>& __rhs) 499 { return __lhs._M_base() < __rhs._M_base(); } 500 501 template<typename _Tp, typename _Alloc> 502 inline bool 503 operator<=(const vector<_Tp, _Alloc>& __lhs, 504 const vector<_Tp, _Alloc>& __rhs) 505 { return __lhs._M_base() <= __rhs._M_base(); } 506 507 template<typename _Tp, typename _Alloc> 508 inline bool 509 operator>=(const vector<_Tp, _Alloc>& __lhs, 510 const vector<_Tp, _Alloc>& __rhs) 511 { return __lhs._M_base() >= __rhs._M_base(); } 512 513 template<typename _Tp, typename _Alloc> 514 inline bool 515 operator>(const vector<_Tp, _Alloc>& __lhs, 516 const vector<_Tp, _Alloc>& __rhs) 517 { return __lhs._M_base() > __rhs._M_base(); } 518 519 template<typename _Tp, typename _Alloc> 520 inline void 521 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 522 { __lhs.swap(__rhs); } 523 524 #if __cplusplus >= 201103L 525 template<typename _Tp, typename _Alloc> 526 inline void 527 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 528 { __lhs.swap(__rhs); } 529 530 template<typename _Tp, typename _Alloc> 531 inline void 532 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 533 { __lhs.swap(__rhs); } 534 #endif 535 536 } // namespace __profile 537 538 #if __cplusplus >= 201103L 539 // DR 1182. 540 /// std::hash specialization for vector<bool>. 541 template<typename _Alloc> 542 struct hash<__profile::vector<bool, _Alloc>> 543 : public __hash_base<size_t, __profile::vector<bool, _Alloc>> 544 { 545 size_t 546 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept 547 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 548 (__b._M_base()); } 549 }; 550 #endif 551 552 } // namespace std 553 554 #endif 555