xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/profile/vector (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
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
36namespace std _GLIBCXX_VISIBILITY(default)
37{
38namespace __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
555