libstdc++
profile/vector
Go to the documentation of this file.
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>
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  void
378  insert(iterator __position, initializer_list<value_type> __l)
379  { this->insert(__position, __l.begin(), __l.end()); }
380 #endif
381 
382 #if __cplusplus >= 201103L
383  void
384  swap(vector&& __x)
385  {
386  _Base::swap(__x);
387  }
388 #endif
389 
390  void
391  swap(vector& __x)
392 #if __cplusplus >= 201103L
393  noexcept(_Alloc_traits::_S_nothrow_swap())
394 #endif
395  {
396  _Base::swap(__x);
397  }
398 
399  void
400  insert(iterator __position, size_type __n, const _Tp& __x)
401  {
402  __profcxx_vector_insert(this, __position.base() - _Base::begin(),
403  this->size());
404  size_type __old_size = this->capacity();
405  _Base::insert(__position, __n, __x);
406  _M_profile_resize(this, __old_size, this->capacity());
407  }
408 
409 #if __cplusplus >= 201103L
410  template<typename _InputIterator,
411  typename = std::_RequireInputIter<_InputIterator>>
412 #else
413  template<typename _InputIterator>
414 #endif
415  void
416  insert(iterator __position,
417  _InputIterator __first, _InputIterator __last)
418  {
419  __profcxx_vector_insert(this, __position.base()-_Base::begin(),
420  this->size());
421  size_type __old_size = this->capacity();
422  _Base::insert(__position, __first, __last);
423  _M_profile_resize(this, __old_size, this->capacity());
424  }
425 
426 
427  iterator
428  erase(iterator __position)
429  {
430  typename _Base::iterator __res = _Base::erase(__position.base());
431  return iterator(__res, this);
432  }
433 
434  iterator
435  erase(iterator __first, iterator __last)
436  {
437  // _GLIBCXX_RESOLVE_LIB_DEFECTS
438  // 151. can't currently clear() empty container
439  typename _Base::iterator __res = _Base::erase(__first.base(),
440  __last.base());
441  return iterator(__res, this);
442  }
443 
444  void
445  clear() _GLIBCXX_NOEXCEPT
446  {
447  __profcxx_vector_destruct(this, this->capacity(), this->size());
448  __profcxx_vector_destruct2(this);
449  _Base::clear();
450  }
451 
452  inline void _M_profile_find() const
453  {
454  __profcxx_vector_find(this, size());
455  }
456 
457  inline void _M_profile_iterate(int __rewind = 0) const
458  {
459  __profcxx_vector_iterate(this);
460  }
461 
462  private:
463  void _M_profile_resize(void* obj, size_type __old_size,
464  size_type __new_size)
465  {
466  if (__old_size < __new_size) {
467  __profcxx_vector_resize(this, this->size(), __new_size);
468  __profcxx_vector_resize2(this, this->size(), __new_size);
469  }
470  }
471  };
472 
473  template<typename _Tp, typename _Alloc>
474  inline bool
475  operator==(const vector<_Tp, _Alloc>& __lhs,
476  const vector<_Tp, _Alloc>& __rhs)
477  { return __lhs._M_base() == __rhs._M_base(); }
478 
479  template<typename _Tp, typename _Alloc>
480  inline bool
481  operator!=(const vector<_Tp, _Alloc>& __lhs,
482  const vector<_Tp, _Alloc>& __rhs)
483  { return __lhs._M_base() != __rhs._M_base(); }
484 
485  template<typename _Tp, typename _Alloc>
486  inline bool
487  operator<(const vector<_Tp, _Alloc>& __lhs,
488  const vector<_Tp, _Alloc>& __rhs)
489  { return __lhs._M_base() < __rhs._M_base(); }
490 
491  template<typename _Tp, typename _Alloc>
492  inline bool
493  operator<=(const vector<_Tp, _Alloc>& __lhs,
494  const vector<_Tp, _Alloc>& __rhs)
495  { return __lhs._M_base() <= __rhs._M_base(); }
496 
497  template<typename _Tp, typename _Alloc>
498  inline bool
499  operator>=(const vector<_Tp, _Alloc>& __lhs,
500  const vector<_Tp, _Alloc>& __rhs)
501  { return __lhs._M_base() >= __rhs._M_base(); }
502 
503  template<typename _Tp, typename _Alloc>
504  inline bool
505  operator>(const vector<_Tp, _Alloc>& __lhs,
506  const vector<_Tp, _Alloc>& __rhs)
507  { return __lhs._M_base() > __rhs._M_base(); }
508 
509  template<typename _Tp, typename _Alloc>
510  inline void
511  swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
512  { __lhs.swap(__rhs); }
513 
514 #if __cplusplus >= 201103L
515  template<typename _Tp, typename _Alloc>
516  inline void
517  swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
518  { __lhs.swap(__rhs); }
519 
520  template<typename _Tp, typename _Alloc>
521  inline void
522  swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
523  { __lhs.swap(__rhs); }
524 #endif
525 
526 } // namespace __profile
527 
528 #if __cplusplus >= 201103L
529  // DR 1182.
530  /// std::hash specialization for vector<bool>.
531  template<typename _Alloc>
532  struct hash<__profile::vector<bool, _Alloc>>
533  : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
534  {
535  size_t
536  operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
538  (__b._M_base()); }
539  };
540 #endif
541 
542 } // namespace std
543 
544 #endif