libstdc++
profile/vector
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