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