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 42namespace std 43{ 44namespace __profile 45{ 46 template<typename _Tp, 47 typename _Allocator = std::allocator<_Tp> > 48 class vector 49 : public _GLIBCXX_STD_PR::vector<_Tp, _Allocator> 50 { 51 typedef _GLIBCXX_STD_PR::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 vector(const _Allocator& __a = _Allocator()) 80 : _Base(__a) 81 { 82 __profcxx_vector_construct(this, this->capacity()); 83 __profcxx_vector_construct2(this); 84 } 85 86 explicit vector(size_type __n, const _Tp& __value = _Tp(), 87 const _Allocator& __a = _Allocator()) 88 : _Base(__n, __value, __a) 89 { 90 __profcxx_vector_construct(this, this->capacity()); 91 __profcxx_vector_construct2(this); 92 } 93 94 template<class _InputIterator> 95 vector(_InputIterator __first, _InputIterator __last, 96 const _Allocator& __a = _Allocator()) 97 : _Base(__first, __last, __a) 98 { 99 __profcxx_vector_construct(this, this->capacity()); 100 __profcxx_vector_construct2(this); 101 } 102 103 vector(const vector& __x) 104 : _Base(__x) 105 { 106 __profcxx_vector_construct(this, this->capacity()); 107 __profcxx_vector_construct2(this); 108 } 109 110 /// Construction from a release-mode vector 111 vector(const _Base& __x) 112 : _Base(__x) 113 { 114 __profcxx_vector_construct(this, this->capacity()); 115 __profcxx_vector_construct2(this); 116 } 117 118#ifdef __GXX_EXPERIMENTAL_CXX0X__ 119 vector(vector&& __x) 120 : _Base(std::forward<vector>(__x)) 121 { 122 __profcxx_vector_construct(this, this->capacity()); 123 __profcxx_vector_construct2(this); 124 } 125 126 vector(initializer_list<value_type> __l, 127 const allocator_type& __a = allocator_type()) 128 : _Base(__l, __a) { } 129#endif 130 131 ~vector() { 132 __profcxx_vector_destruct(this, this->capacity(), this->size()); 133 __profcxx_vector_destruct2(this); 134 } 135 136 vector& 137 operator=(const vector& __x) 138 { 139 static_cast<_Base&>(*this) = __x; 140 return *this; 141 } 142 143#ifdef __GXX_EXPERIMENTAL_CXX0X__ 144 vector& 145 operator=(vector&& __x) 146 { 147 // NB: DR 1204. 148 // NB: DR 675. 149 this->clear(); 150 this->swap(__x); 151 return *this; 152 } 153 154 vector& 155 operator=(initializer_list<value_type> __l) 156 { 157 static_cast<_Base&>(*this) = __l; 158 return *this; 159 } 160#endif 161 162 using _Base::assign; 163 using _Base::get_allocator; 164 165 166 // iterators: 167 iterator 168 begin() 169 { return iterator(_Base::begin(), this); } 170 171 const_iterator 172 begin() const 173 { return const_iterator(_Base::begin(), this); } 174 175 iterator 176 end() 177 { return iterator(_Base::end(), this); } 178 179 const_iterator 180 end() const 181 { return const_iterator(_Base::end(), this); } 182 183 reverse_iterator 184 rbegin() 185 { return reverse_iterator(end()); } 186 187 const_reverse_iterator 188 rbegin() const 189 { return const_reverse_iterator(end()); } 190 191 reverse_iterator 192 rend() 193 { return reverse_iterator(begin()); } 194 195 const_reverse_iterator 196 rend() const 197 { return const_reverse_iterator(begin()); } 198 199#ifdef __GXX_EXPERIMENTAL_CXX0X__ 200 const_iterator 201 cbegin() const 202 { return const_iterator(_Base::begin(), this); } 203 204 const_iterator 205 cend() const 206 { return const_iterator(_Base::end(), this); } 207 208 const_reverse_iterator 209 crbegin() const 210 { return const_reverse_iterator(end()); } 211 212 const_reverse_iterator 213 crend() const 214 { return const_reverse_iterator(begin()); } 215#endif 216 217 // 23.2.4.2 capacity: 218 using _Base::size; 219 using _Base::max_size; 220 221 void 222 resize(size_type __sz, _Tp __c = _Tp()) 223 { 224 __profcxx_vector_invalid_operator(this); 225 _M_profile_resize(this, this->capacity(), __sz); 226 _Base::resize(__sz, __c); 227 } 228 229#ifdef __GXX_EXPERIMENTAL_CXX0X__ 230 using _Base::shrink_to_fit; 231#endif 232 233 using _Base::empty; 234 235 // element access: 236 reference 237 operator[](size_type __n) 238 { 239 __profcxx_vector_invalid_operator(this); 240 return _M_base()[__n]; 241 } 242 const_reference 243 operator[](size_type __n) const 244 { 245 __profcxx_vector_invalid_operator(this); 246 return _M_base()[__n]; 247 } 248 249 using _Base::at; 250 251 reference 252 front() 253 { 254 return _Base::front(); 255 } 256 257 const_reference 258 front() const 259 { 260 return _Base::front(); 261 } 262 263 reference 264 back() 265 { 266 return _Base::back(); 267 } 268 269 const_reference 270 back() const 271 { 272 return _Base::back(); 273 } 274 275 // _GLIBCXX_RESOLVE_LIB_DEFECTS 276 // DR 464. Suggestion for new member functions in standard containers. 277 using _Base::data; 278 279 // 23.2.4.3 modifiers: 280 void 281 push_back(const _Tp& __x) 282 { 283 size_type __old_size = this->capacity(); 284 _Base::push_back(__x); 285 _M_profile_resize(this, __old_size, this->capacity()); 286 } 287 288#ifdef __GXX_EXPERIMENTAL_CXX0X__ 289 void 290 push_back(_Tp&& __x) 291 { 292 size_type __old_size = this->capacity(); 293 _Base::push_back(__x); 294 _M_profile_resize(this, __old_size, this->capacity()); 295 } 296 297#endif 298 299 iterator 300 insert(iterator __position, const _Tp& __x) 301 { 302 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 303 this->size()); 304 size_type __old_size = this->capacity(); 305 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 306 _M_profile_resize(this, __old_size, this->capacity()); 307 return iterator(__res, this); 308 } 309 310#ifdef __GXX_EXPERIMENTAL_CXX0X__ 311 iterator 312 insert(iterator __position, _Tp&& __x) 313 { 314 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 315 this->size()); 316 size_type __old_size = this->capacity(); 317 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 318 _M_profile_resize(this, __old_size, this->capacity()); 319 return iterator(__res, this); 320 } 321 322 void 323 insert(iterator __position, initializer_list<value_type> __l) 324 { this->insert(__position, __l.begin(), __l.end()); } 325#endif 326 327#ifdef __GXX_EXPERIMENTAL_CXX0X__ 328 void 329 swap(vector&& __x) 330 { 331 _Base::swap(__x); 332 } 333#endif 334 335 void 336 swap(vector& __x) 337 { 338 _Base::swap(__x); 339 } 340 341 void 342 insert(iterator __position, size_type __n, const _Tp& __x) 343 { 344 __profcxx_vector_insert(this, __position.base() - _Base::begin(), 345 this->size()); 346 size_type __old_size = this->capacity(); 347 _Base::insert(__position, __n, __x); 348 _M_profile_resize(this, __old_size, this->capacity()); 349 } 350 351 template<class _InputIterator> 352 void 353 insert(iterator __position, 354 _InputIterator __first, _InputIterator __last) 355 { 356 __profcxx_vector_insert(this, __position.base()-_Base::begin(), 357 this->size()); 358 size_type __old_size = this->capacity(); 359 _Base::insert(__position, __first, __last); 360 _M_profile_resize(this, __old_size, this->capacity()); 361 } 362 363 364 iterator 365 erase(iterator __position) 366 { 367 typename _Base::iterator __res = _Base::erase(__position.base()); 368 return iterator(__res, this); 369 } 370 371 iterator 372 erase(iterator __first, iterator __last) 373 { 374 // _GLIBCXX_RESOLVE_LIB_DEFECTS 375 // 151. can't currently clear() empty container 376 typename _Base::iterator __res = _Base::erase(__first.base(), 377 __last.base()); 378 return iterator(__res, this); 379 } 380 381 void 382 clear() 383 { 384 __profcxx_vector_destruct(this, this->capacity(), this->size()); 385 __profcxx_vector_destruct2(this); 386 _Base::clear(); 387 } 388 389 inline void _M_profile_find() const 390 { 391 __profcxx_vector_find(this, size()); 392 } 393 394 inline void _M_profile_iterate(int __rewind = 0) const 395 { 396 __profcxx_vector_iterate(this); 397 } 398 399 private: 400 void _M_profile_resize(void* obj, size_type __old_size, 401 size_type __new_size) 402 { 403 if (__old_size < __new_size) { 404 __profcxx_vector_resize(this, this->size(), __new_size); 405 __profcxx_vector_resize2(this, this->size(), __new_size); 406 } 407 } 408 }; 409 410 template<typename _Tp, typename _Alloc> 411 inline bool 412 operator==(const vector<_Tp, _Alloc>& __lhs, 413 const vector<_Tp, _Alloc>& __rhs) 414 { return __lhs._M_base() == __rhs._M_base(); } 415 416 template<typename _Tp, typename _Alloc> 417 inline bool 418 operator!=(const vector<_Tp, _Alloc>& __lhs, 419 const vector<_Tp, _Alloc>& __rhs) 420 { return __lhs._M_base() != __rhs._M_base(); } 421 422 template<typename _Tp, typename _Alloc> 423 inline bool 424 operator<(const vector<_Tp, _Alloc>& __lhs, 425 const vector<_Tp, _Alloc>& __rhs) 426 { return __lhs._M_base() < __rhs._M_base(); } 427 428 template<typename _Tp, typename _Alloc> 429 inline bool 430 operator<=(const vector<_Tp, _Alloc>& __lhs, 431 const vector<_Tp, _Alloc>& __rhs) 432 { return __lhs._M_base() <= __rhs._M_base(); } 433 434 template<typename _Tp, typename _Alloc> 435 inline bool 436 operator>=(const vector<_Tp, _Alloc>& __lhs, 437 const vector<_Tp, _Alloc>& __rhs) 438 { return __lhs._M_base() >= __rhs._M_base(); } 439 440 template<typename _Tp, typename _Alloc> 441 inline bool 442 operator>(const vector<_Tp, _Alloc>& __lhs, 443 const vector<_Tp, _Alloc>& __rhs) 444 { return __lhs._M_base() > __rhs._M_base(); } 445 446 template<typename _Tp, typename _Alloc> 447 inline void 448 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 449 { __lhs.swap(__rhs); } 450 451#ifdef __GXX_EXPERIMENTAL_CXX0X__ 452 template<typename _Tp, typename _Alloc> 453 inline void 454 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) 455 { __lhs.swap(__rhs); } 456 457 template<typename _Tp, typename _Alloc> 458 inline void 459 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) 460 { __lhs.swap(__rhs); } 461#endif 462 463} // namespace __profile 464 465#ifdef __GXX_EXPERIMENTAL_CXX0X__ 466 // DR 1182. 467 /// std::hash specialization for vector<bool>. 468 template<typename _Alloc> 469 struct hash<__profile::vector<bool, _Alloc>> 470 : public std::unary_function<__profile::vector<bool, _Alloc>, size_t> 471 { 472 size_t 473 operator()(const __profile::vector<bool, _Alloc>& __b) const 474 { return std::hash<_GLIBCXX_STD_D::vector<bool, _Alloc>>() 475 (__b._M_base()); } 476 }; 477#endif 478 479} // namespace std 480 481#endif 482