libstdc++
profile/vector
Go to the documentation of this file.
1 // Profiling vector implementation -*- C++ -*-
2 
3 // Copyright (C) 2009-2014 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>
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  typedef typename _Base::iterator _Base_iterator;
48  typedef typename _Base::const_iterator _Base_const_iterator;
49 
50 #if __cplusplus >= 201103L
51  typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
52 #endif
53 
54  public:
55  typedef typename _Base::reference reference;
56  typedef typename _Base::const_reference const_reference;
57 
58  typedef __iterator_tracker<_Base_iterator, vector>
59  iterator;
60  typedef __iterator_tracker<_Base_const_iterator, vector>
61  const_iterator;
62 
63  typedef typename _Base::size_type size_type;
64  typedef typename _Base::difference_type difference_type;
65 
66  typedef _Tp value_type;
67  typedef _Allocator allocator_type;
68  typedef typename _Base::pointer pointer;
69  typedef typename _Base::const_pointer const_pointer;
70  typedef std::reverse_iterator<iterator> reverse_iterator;
71  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
72 
73  _Base&
74  _M_base() _GLIBCXX_NOEXCEPT { return *this; }
75 
76  const _Base&
77  _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
78 
79  // 23.2.4.1 construct/copy/destroy:
80  explicit
81  vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT
82  : _Base(__a)
83  {
84  __profcxx_vector_construct(this, this->capacity());
85  __profcxx_vector_construct2(this);
86  }
87 
88 #if __cplusplus >= 201103L
89  explicit
90  vector(size_type __n, const _Allocator& __a = _Allocator())
91  : _Base(__n, __a)
92  {
93  __profcxx_vector_construct(this, this->capacity());
94  __profcxx_vector_construct2(this);
95  }
96 
97  vector(size_type __n, const _Tp& __value,
98  const _Allocator& __a = _Allocator())
99  : _Base(__n, __value, __a)
100  {
101  __profcxx_vector_construct(this, this->capacity());
102  __profcxx_vector_construct2(this);
103  }
104 #else
105  explicit
106  vector(size_type __n, const _Tp& __value = _Tp(),
107  const _Allocator& __a = _Allocator())
108  : _Base(__n, __value, __a)
109  {
110  __profcxx_vector_construct(this, this->capacity());
111  __profcxx_vector_construct2(this);
112  }
113 #endif
114 
115 #if __cplusplus >= 201103L
116  template<typename _InputIterator,
117  typename = std::_RequireInputIter<_InputIterator>>
118 #else
119  template<typename _InputIterator>
120 #endif
121  vector(_InputIterator __first, _InputIterator __last,
122  const _Allocator& __a = _Allocator())
123  : _Base(__first, __last, __a)
124  {
125  __profcxx_vector_construct(this, this->capacity());
126  __profcxx_vector_construct2(this);
127  }
128 
129  vector(const vector& __x)
130  : _Base(__x)
131  {
132  __profcxx_vector_construct(this, this->capacity());
133  __profcxx_vector_construct2(this);
134  }
135 
136  /// Construction from a release-mode vector
137  vector(const _Base& __x)
138  : _Base(__x)
139  {
140  __profcxx_vector_construct(this, this->capacity());
141  __profcxx_vector_construct2(this);
142  }
143 
144 #if __cplusplus >= 201103L
145  vector(vector&& __x) noexcept
146  : _Base(std::move(__x))
147  {
148  __profcxx_vector_construct(this, this->capacity());
149  __profcxx_vector_construct2(this);
150  }
151 
152  vector(const _Base& __x, const _Allocator& __a)
153  : _Base(__x, __a)
154  {
155  __profcxx_vector_construct(this, this->capacity());
156  __profcxx_vector_construct2(this);
157  }
158 
159  vector(vector&& __x, const _Allocator& __a)
160  : _Base(std::move(__x), __a)
161  {
162  __profcxx_vector_construct(this, this->capacity());
163  __profcxx_vector_construct2(this);
164  }
165 
166  vector(initializer_list<value_type> __l,
167  const allocator_type& __a = allocator_type())
168  : _Base(__l, __a) { }
169 #endif
170 
171  ~vector() _GLIBCXX_NOEXCEPT
172  {
173  __profcxx_vector_destruct(this, this->capacity(), this->size());
174  __profcxx_vector_destruct2(this);
175  }
176 
177  vector&
178  operator=(const vector& __x)
179  {
180  static_cast<_Base&>(*this) = __x;
181  return *this;
182  }
183 
184 #if __cplusplus >= 201103L
185  vector&
186  operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
187  {
188  __profcxx_vector_destruct(this, this->capacity(), this->size());
189  __profcxx_vector_destruct2(this);
190  static_cast<_Base&>(*this) = std::move(__x);
191  return *this;
192  }
193 
194  vector&
195  operator=(initializer_list<value_type> __l)
196  {
197  static_cast<_Base&>(*this) = __l;
198  return *this;
199  }
200 #endif
201 
202  using _Base::assign;
203  using _Base::get_allocator;
204 
205 
206  // iterators:
207  iterator
208  begin() _GLIBCXX_NOEXCEPT
209  { return iterator(_Base::begin(), this); }
210 
211  const_iterator
212  begin() const _GLIBCXX_NOEXCEPT
213  { return const_iterator(_Base::begin(), this); }
214 
215  iterator
216  end() _GLIBCXX_NOEXCEPT
217  { return iterator(_Base::end(), this); }
218 
219  const_iterator
220  end() const _GLIBCXX_NOEXCEPT
221  { return const_iterator(_Base::end(), this); }
222 
223  reverse_iterator
224  rbegin() _GLIBCXX_NOEXCEPT
225  { return reverse_iterator(end()); }
226 
227  const_reverse_iterator
228  rbegin() const _GLIBCXX_NOEXCEPT
229  { return const_reverse_iterator(end()); }
230 
231  reverse_iterator
232  rend() _GLIBCXX_NOEXCEPT
233  { return reverse_iterator(begin()); }
234 
235  const_reverse_iterator
236  rend() const _GLIBCXX_NOEXCEPT
237  { return const_reverse_iterator(begin()); }
238 
239 #if __cplusplus >= 201103L
240  const_iterator
241  cbegin() const noexcept
242  { return const_iterator(_Base::begin(), this); }
243 
244  const_iterator
245  cend() const noexcept
246  { return const_iterator(_Base::end(), this); }
247 
248  const_reverse_iterator
249  crbegin() const noexcept
250  { return const_reverse_iterator(end()); }
251 
252  const_reverse_iterator
253  crend() const noexcept
254  { return const_reverse_iterator(begin()); }
255 #endif
256 
257  // 23.2.4.2 capacity:
258  using _Base::size;
259  using _Base::max_size;
260 
261 #if __cplusplus >= 201103L
262  void
263  resize(size_type __sz)
264  {
265  __profcxx_vector_invalid_operator(this);
266  _M_profile_resize(this, this->capacity(), __sz);
267  _Base::resize(__sz);
268  }
269 
270  void
271  resize(size_type __sz, const _Tp& __c)
272  {
273  __profcxx_vector_invalid_operator(this);
274  _M_profile_resize(this, this->capacity(), __sz);
275  _Base::resize(__sz, __c);
276  }
277 #else
278  void
279  resize(size_type __sz, _Tp __c = _Tp())
280  {
281  __profcxx_vector_invalid_operator(this);
282  _M_profile_resize(this, this->capacity(), __sz);
283  _Base::resize(__sz, __c);
284  }
285 #endif
286 
287 #if __cplusplus >= 201103L
288  using _Base::shrink_to_fit;
289 #endif
290 
291  using _Base::empty;
292 
293  // element access:
294  reference
295  operator[](size_type __n) _GLIBCXX_NOEXCEPT
296  {
297  __profcxx_vector_invalid_operator(this);
298  return _M_base()[__n];
299  }
300  const_reference
301  operator[](size_type __n) const _GLIBCXX_NOEXCEPT
302  {
303  __profcxx_vector_invalid_operator(this);
304  return _M_base()[__n];
305  }
306 
307  using _Base::at;
308 
309  reference
310  front() _GLIBCXX_NOEXCEPT
311  {
312  return _Base::front();
313  }
314 
315  const_reference
316  front() const _GLIBCXX_NOEXCEPT
317  {
318  return _Base::front();
319  }
320 
321  reference
322  back() _GLIBCXX_NOEXCEPT
323  {
324  return _Base::back();
325  }
326 
327  const_reference
328  back() const _GLIBCXX_NOEXCEPT
329  {
330  return _Base::back();
331  }
332 
333  // _GLIBCXX_RESOLVE_LIB_DEFECTS
334  // DR 464. Suggestion for new member functions in standard containers.
335  using _Base::data;
336 
337  // 23.2.4.3 modifiers:
338  void
339  push_back(const _Tp& __x)
340  {
341  size_type __old_size = this->capacity();
342  _Base::push_back(__x);
343  _M_profile_resize(this, __old_size, this->capacity());
344  }
345 
346 #if __cplusplus >= 201103L
347  void
348  push_back(_Tp&& __x)
349  {
350  size_type __old_size = this->capacity();
351  _Base::push_back(std::move(__x));
352  _M_profile_resize(this, __old_size, this->capacity());
353  }
354 
355 #endif
356 
357  iterator
358 #if __cplusplus >= 201103L
359  insert(const_iterator __position, const _Tp& __x)
360 #else
361  insert(iterator __position, const _Tp& __x)
362 #endif
363  {
364  __profcxx_vector_insert(this, __position.base() - _Base::begin(),
365  this->size());
366  size_type __old_size = this->capacity();
367  _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 #if __cplusplus >= 201103L
373  iterator
374  insert(const_iterator __position, _Tp&& __x)
375  {
376  __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
377  this->size());
378  size_type __old_size = this->capacity();
379  _Base_iterator __res = _Base::insert(__position.base(), __x);
380  _M_profile_resize(this, __old_size, this->capacity());
381  return iterator(__res, this);
382  }
383 
384  template<typename... _Args>
385  iterator
386  emplace(const_iterator __position, _Args&&... __args)
387  {
388  _Base_iterator __res = _Base::emplace(__position.base(),
389  std::forward<_Args>(__args)...);
390  return iterator(__res, this);
391  }
392 
393  iterator
394  insert(const_iterator __position, initializer_list<value_type> __l)
395  { return this->insert(__position, __l.begin(), __l.end()); }
396 #endif
397 
398 #if __cplusplus >= 201103L
399  void
400  swap(vector&& __x)
401  {
402  _Base::swap(__x);
403  }
404 #endif
405 
406  void
407  swap(vector& __x)
408 #if __cplusplus >= 201103L
409  noexcept(_Alloc_traits::_S_nothrow_swap())
410 #endif
411  {
412  _Base::swap(__x);
413  }
414 
415 #if __cplusplus >= 201103L
416  iterator
417  insert(const_iterator __position, size_type __n, const _Tp& __x)
418  {
419  __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
420  this->size());
421  size_type __old_size = this->capacity();
422  _Base_iterator __res = _Base::insert(__position, __n, __x);
423  _M_profile_resize(this, __old_size, this->capacity());
424  return iterator(__res, this);
425  }
426 #else
427  void
428  insert(iterator __position, size_type __n, const _Tp& __x)
429  {
430  __profcxx_vector_insert(this, __position.base() - _Base::begin(),
431  this->size());
432  size_type __old_size = this->capacity();
433  _Base::insert(__position, __n, __x);
434  _M_profile_resize(this, __old_size, this->capacity());
435  }
436 #endif
437 
438 #if __cplusplus >= 201103L
439  template<typename _InputIterator,
440  typename = std::_RequireInputIter<_InputIterator>>
441  iterator
442  insert(const_iterator __position,
443  _InputIterator __first, _InputIterator __last)
444  {
445  __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
446  this->size());
447  size_type __old_size = this->capacity();
448  _Base_iterator __res = _Base::insert(__position, __first, __last);
449  _M_profile_resize(this, __old_size, this->capacity());
450  return iterator(__res, this);
451  }
452 #else
453  template<typename _InputIterator>
454  void
455  insert(iterator __position,
456  _InputIterator __first, _InputIterator __last)
457  {
458  __profcxx_vector_insert(this, __position.base() - _Base::begin(),
459  this->size());
460  size_type __old_size = this->capacity();
461  _Base::insert(__position, __first, __last);
462  _M_profile_resize(this, __old_size, this->capacity());
463  }
464 #endif
465 
466  iterator
467 #if __cplusplus >= 201103L
468  erase(const_iterator __position)
469 #else
470  erase(iterator __position)
471 #endif
472  {
473  _Base_iterator __res = _Base::erase(__position.base());
474  return iterator(__res, this);
475  }
476 
477  iterator
478 #if __cplusplus >= 201103L
479  erase(const_iterator __first, const_iterator __last)
480 #else
481  erase(iterator __first, iterator __last)
482 #endif
483  {
484  // _GLIBCXX_RESOLVE_LIB_DEFECTS
485  // 151. can't currently clear() empty container
486  _Base_iterator __res = _Base::erase(__first.base(), __last.base());
487  return iterator(__res, this);
488  }
489 
490  void
491  clear() _GLIBCXX_NOEXCEPT
492  {
493  __profcxx_vector_destruct(this, this->capacity(), this->size());
494  __profcxx_vector_destruct2(this);
495  _Base::clear();
496  }
497 
498  inline void _M_profile_find() const
499  {
500  __profcxx_vector_find(this, size());
501  }
502 
503  inline void _M_profile_iterate(int __rewind = 0) const
504  {
505  __profcxx_vector_iterate(this);
506  }
507 
508  private:
509  void _M_profile_resize(void* obj, size_type __old_size,
510  size_type __new_size)
511  {
512  if (__old_size < __new_size) {
513  __profcxx_vector_resize(this, this->size(), __new_size);
514  __profcxx_vector_resize2(this, this->size(), __new_size);
515  }
516  }
517  };
518 
519  template<typename _Tp, typename _Alloc>
520  inline bool
521  operator==(const vector<_Tp, _Alloc>& __lhs,
522  const vector<_Tp, _Alloc>& __rhs)
523  { return __lhs._M_base() == __rhs._M_base(); }
524 
525  template<typename _Tp, typename _Alloc>
526  inline bool
527  operator!=(const vector<_Tp, _Alloc>& __lhs,
528  const vector<_Tp, _Alloc>& __rhs)
529  { return __lhs._M_base() != __rhs._M_base(); }
530 
531  template<typename _Tp, typename _Alloc>
532  inline bool
533  operator<(const vector<_Tp, _Alloc>& __lhs,
534  const vector<_Tp, _Alloc>& __rhs)
535  { return __lhs._M_base() < __rhs._M_base(); }
536 
537  template<typename _Tp, typename _Alloc>
538  inline bool
539  operator<=(const vector<_Tp, _Alloc>& __lhs,
540  const vector<_Tp, _Alloc>& __rhs)
541  { return __lhs._M_base() <= __rhs._M_base(); }
542 
543  template<typename _Tp, typename _Alloc>
544  inline bool
545  operator>=(const vector<_Tp, _Alloc>& __lhs,
546  const vector<_Tp, _Alloc>& __rhs)
547  { return __lhs._M_base() >= __rhs._M_base(); }
548 
549  template<typename _Tp, typename _Alloc>
550  inline bool
551  operator>(const vector<_Tp, _Alloc>& __lhs,
552  const vector<_Tp, _Alloc>& __rhs)
553  { return __lhs._M_base() > __rhs._M_base(); }
554 
555  template<typename _Tp, typename _Alloc>
556  inline void
557  swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
558  { __lhs.swap(__rhs); }
559 
560 #if __cplusplus >= 201103L
561  template<typename _Tp, typename _Alloc>
562  inline void
563  swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
564  { __lhs.swap(__rhs); }
565 
566  template<typename _Tp, typename _Alloc>
567  inline void
568  swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
569  { __lhs.swap(__rhs); }
570 #endif
571 
572 } // namespace __profile
573 
574 #if __cplusplus >= 201103L
575  // DR 1182.
576  /// std::hash specialization for vector<bool>.
577  template<typename _Alloc>
578  struct hash<__profile::vector<bool, _Alloc>>
579  : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
580  {
581  size_t
582  operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
584  (__b._M_base()); }
585  };
586 #endif
587 
588 } // namespace std
589 
590 #endif
Uniform interface to C++98 and C++0x allocators.
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to the first element of the initializer_list.
constexpr size_t size() const noexcept
Returns the total number of bits.
Definition: bitset:1293
The standard allocator, as per [20.4].
Definition: allocator.h:92
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initializer_list. ...
void swap(function< _Res(_Args...)> &__x, function< _Res(_Args...)> &__y)
Swap the targets of two polymorphic function object wrappers.
Definition: functional:2534
Sequential helper functions. This file is a GNU profile extension to the Standard C++ Library...
Primary class template hash.
Definition: system_error:115
reference operator[](size_t __position)
Array-indexing support.
Definition: bitset:1156