2014-11-10 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / libstdc++-v3 / include / profile / vector
blobdf7f3b5e9b6753626a0efc00826a947bfaced7b3
1 // Profiling vector implementation -*- C++ -*-
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.
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.
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.
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/>.
24 /** @file profile/vector
25  *  This file is a GNU profile extension to the Standard C++ Library.
26  */
28 #ifndef _GLIBCXX_PROFILE_VECTOR
29 #define _GLIBCXX_PROFILE_VECTOR 1
31 #include <vector>
32 #include <utility>
33 #include <profile/base.h>
34 #include <profile/iterator_tracker.h>
36 namespace std _GLIBCXX_VISIBILITY(default)
38 namespace __profile
40   template<typename _Vector>
41     class _Vector_profile_pre
42     {
43       _Vector&
44       _M_conjure()
45       { return *static_cast<_Vector*>(this); }
47     public:
48 #if __cplusplus >= 201103L
49       _Vector_profile_pre() = default;
50       _Vector_profile_pre(const _Vector_profile_pre&) = default;
51       _Vector_profile_pre(_Vector_profile_pre&&) = default;
53       _Vector_profile_pre&
54       operator=(const _Vector_profile_pre&)
55       { _M_conjure()._M_profile_destruct(); }
57       _Vector_profile_pre&
58       operator=(_Vector_profile_pre&&) noexcept
59       { _M_conjure()._M_profile_destruct(); }
60 #endif
61     };
63   template<typename _Vector>
64     class _Vector_profile_post
65     {
66       _Vector&
67       _M_conjure()
68       { return *static_cast<_Vector*>(this); }
70     protected:
71       __gnu_profile::__container_size_info* _M_size_info;
72       __gnu_profile::__vector2list_info* _M_vect2list_info;
74       _Vector_profile_post() _GLIBCXX_NOEXCEPT
75       { _M_profile_construct(); }
77 #if __cplusplus >= 201103L
78       _Vector_profile_post(const _Vector_profile_post&) noexcept
79       : _Vector_profile_post() { }
80       _Vector_profile_post(_Vector_profile_post&& __other) noexcept
81       : _Vector_profile_post()
82       { _M_swap(__other); }
84       _Vector_profile_post&
85       operator=(const _Vector_profile_post&) noexcept
86       { _M_profile_construct(); }
88       _Vector_profile_post&
89       operator=(_Vector_profile_post&& __other) noexcept
90       {
91         _M_swap(__other);
92         __other._M_profile_construct();
93       }
94 #endif
96       ~_Vector_profile_post()
97       { _M_conjure()._M_profile_destruct(); }
99     public:
100       void
101       _M_profile_construct() _GLIBCXX_NOEXCEPT
102       {
103         _M_size_info =
104           __profcxx_vector_size_construct(_M_conjure().capacity());
105         _M_vect2list_info = __profcxx_vector2list_construct();  
106       }
108       void
109       _M_profile_destruct() _GLIBCXX_NOEXCEPT
110       {
111         __profcxx_vector2list_destruct(_M_vect2list_info);
112         _M_vect2list_info = 0;
113         __profcxx_vector_size_destruct(_M_size_info,
114                                        _M_conjure().capacity(),
115                                        _M_conjure().size());
116         _M_size_info = 0;
117       }
119       void
120       _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT
121       {
122         std::swap(_M_size_info, __other._M_size_info);
123         std::swap(_M_vect2list_info, __other._M_vect2list_info);
124       }
125     };
127   template<typename _Tp,
128            typename _Allocator = std::allocator<_Tp> >
129     class vector
130     : public _Vector_profile_pre<vector<_Tp, _Allocator> >,
131       public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
132       public _Vector_profile_post<vector<_Tp, _Allocator> >
133     {
134       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>   _Base;
136       typedef typename _Base::iterator                  _Base_iterator;
137       typedef typename _Base::const_iterator            _Base_const_iterator;
139     public:
140       typedef typename _Base::reference                 reference;
141       typedef typename _Base::const_reference           const_reference;
143       typedef __iterator_tracker<_Base_iterator, vector>
144                                                         iterator;
145       typedef __iterator_tracker<_Base_const_iterator, vector>
146                                                         const_iterator;
148       typedef typename _Base::size_type                 size_type;
149       typedef typename _Base::difference_type           difference_type;
151       typedef _Tp                                       value_type;
152       typedef _Allocator                                allocator_type;
153       typedef typename _Base::pointer                   pointer;
154       typedef typename _Base::const_pointer             const_pointer;
155       typedef std::reverse_iterator<iterator>           reverse_iterator;
156       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
158       _Base&
159       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
161       const _Base&
162       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
164       // 23.2.4.1 construct/copy/destroy:
166 #if __cplusplus < 201103L
167       vector()
168       { }
170       vector(const vector& __x)
171       : _Base(__x) { }
172 #else
173       vector() = default;
174       vector(const vector&) = default;
175       vector(vector&&) = default;
176 #endif
178       explicit
179       vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
180       : _Base(__a) { }
182 #if __cplusplus >= 201103L
183       explicit
184       vector(size_type __n, const _Allocator& __a = _Allocator())
185       : _Base(__n, __a) { }
187       vector(size_type __n, const _Tp& __value,
188              const _Allocator& __a = _Allocator())
189       : _Base(__n, __value, __a) { }
190 #else
191       explicit
192       vector(size_type __n, const _Tp& __value = _Tp(),
193              const _Allocator& __a = _Allocator())
194       : _Base(__n, __value, __a) { }
195 #endif
197 #if __cplusplus >= 201103L
198       template<typename _InputIterator,
199                typename = std::_RequireInputIter<_InputIterator>>
200 #else
201       template<typename _InputIterator>
202 #endif
203         vector(_InputIterator __first, _InputIterator __last,
204                const _Allocator& __a = _Allocator())
205         : _Base(__first, __last, __a) { }
207       /// Construction from a normal-mode vector
208       vector(const _Base& __x)
209       : _Base(__x) { }
211 #if __cplusplus >= 201103L
212       vector(const _Base& __x, const _Allocator& __a)
213       : _Base(__x, __a) { }
215       vector(vector&& __x, const _Allocator& __a)
216       : _Base(std::move(__x), __a) { }
218       vector(initializer_list<value_type> __l,
219              const allocator_type& __a = allocator_type())
220       : _Base(__l, __a) { }
221 #endif
223 #if __cplusplus < 201103L
224       vector&
225       operator=(const vector& __x)
226       {
227         this->_M_profile_destruct();
228         _M_base() = __x;
229         this->_M_profile_construct();
230         return *this;
231       }
232 #else
233       vector&
234       operator=(const vector&) = default;
236       vector&
237       operator=(vector&&) = default;
239       vector&
240       operator=(initializer_list<value_type> __l)
241       {
242         this->_M_profile_destruct();
243         _M_base() = __l;
244         this->_M_profile_construct();
245         return *this;
246       }
247 #endif
249       // iterators:
250       iterator
251       begin() _GLIBCXX_NOEXCEPT
252       { return iterator(_Base::begin(), this); }
254       const_iterator
255       begin() const _GLIBCXX_NOEXCEPT
256       { return const_iterator(_Base::begin(), this); }
258       iterator
259       end() _GLIBCXX_NOEXCEPT
260       { return iterator(_Base::end(), this); }
262       const_iterator
263       end() const _GLIBCXX_NOEXCEPT
264       { return const_iterator(_Base::end(), this); }
266       reverse_iterator
267       rbegin() _GLIBCXX_NOEXCEPT
268       { return reverse_iterator(end()); }
270       const_reverse_iterator
271       rbegin() const _GLIBCXX_NOEXCEPT
272       { return const_reverse_iterator(end()); }
274       reverse_iterator
275       rend() _GLIBCXX_NOEXCEPT
276       { return reverse_iterator(begin()); }
278       const_reverse_iterator
279       rend() const _GLIBCXX_NOEXCEPT
280       { return const_reverse_iterator(begin()); }
282 #if __cplusplus >= 201103L
283       const_iterator
284       cbegin() const noexcept
285       { return const_iterator(_Base::begin(), this); }
287       const_iterator
288       cend() const noexcept
289       { return const_iterator(_Base::end(), this); }
291       const_reverse_iterator
292       crbegin() const noexcept
293       { return const_reverse_iterator(end()); }
295       const_reverse_iterator
296       crend() const noexcept
297       { return const_reverse_iterator(begin()); }
298 #endif
300       // 23.2.4.2 capacity:
302 #if __cplusplus >= 201103L
303       void
304       resize(size_type __sz)
305       {
306         __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
307         _M_profile_resize(this->capacity(), __sz);
308         _Base::resize(__sz);
309       }
311       void
312       resize(size_type __sz, const _Tp& __c)
313       {
314         __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
315         _M_profile_resize(this->capacity(), __sz);
316         _Base::resize(__sz, __c);
317       }
318 #else
319       void
320       resize(size_type __sz, _Tp __c = _Tp())
321       {
322         __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
323         _M_profile_resize(this->capacity(), __sz);
324         _Base::resize(__sz, __c);
325       }
326 #endif
328       // element access:
329       reference
330       operator[](size_type __n) _GLIBCXX_NOEXCEPT
331       {
332         __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
333         return _M_base()[__n];
334       }
335       const_reference
336       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
337       {
338         __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
339         return _M_base()[__n];
340       }
342       // 23.2.4.3 modifiers:
343       void
344       push_back(const _Tp& __x)
345       {
346         size_type __old_size = this->capacity();
347         _Base::push_back(__x);
348         _M_profile_resize(__old_size, this->capacity());
349       }
351 #if __cplusplus >= 201103L
352       void
353       push_back(_Tp&& __x)
354       {
355         size_type __old_size = this->capacity();
356         _Base::push_back(std::move(__x));
357         _M_profile_resize(__old_size, this->capacity());
358       }
360 #endif
362       iterator
363 #if __cplusplus >= 201103L
364       insert(const_iterator __pos, const _Tp& __x)
365 #else
366       insert(iterator __pos, const _Tp& __x)
367 #endif
368       {
369         __profcxx_vector2list_insert(this->_M_vect2list_info,
370                                      __pos.base() - _Base::begin(),
371                                      this->size());
372         size_type __old_size = this->capacity();
373         _Base_iterator __res = _Base::insert(__pos.base(), __x);
374         _M_profile_resize(__old_size, this->capacity());
375         return iterator(__res, this);
376       }
378 #if __cplusplus >= 201103L
379       iterator
380       insert(const_iterator __pos, _Tp&& __x)
381       {
382         __profcxx_vector2list_insert(this->_M_vect2list_info,
383                                      __pos.base() - _Base::cbegin(),
384                                      this->size());
385         size_type __old_size = this->capacity();
386         _Base_iterator __res = _Base::insert(__pos.base(), __x);
387         _M_profile_resize(__old_size, this->capacity());
388         return iterator(__res, this);
389       }
391       template<typename... _Args>
392         iterator
393         emplace(const_iterator __pos, _Args&&... __args)
394         {
395           _Base_iterator __res = _Base::emplace(__pos.base(),
396                                                 std::forward<_Args>(__args)...);
397           return iterator(__res, this);
398         }
400       iterator
401       insert(const_iterator __pos, initializer_list<value_type> __l)
402       { return this->insert(__pos, __l.begin(), __l.end()); }
403 #endif
405       void
406       swap(vector& __x)
407 #if __cplusplus >= 201103L
408         noexcept( noexcept(declval<_Base>().swap(__x)) )
409 #endif
410       {
411         _Base::swap(__x);
412         this->_M_swap(__x);
413       }
415 #if __cplusplus >= 201103L
416       iterator
417       insert(const_iterator __pos, size_type __n, const _Tp& __x)
418       {
419         __profcxx_vector2list_insert(this->_M_vect2list_info,
420                                      __pos.base() - _Base::cbegin(),
421                                      this->size());
422         size_type __old_size = this->capacity();
423         _Base_iterator __res = _Base::insert(__pos, __n, __x);
424         _M_profile_resize(__old_size, this->capacity());
425         return iterator(__res, this);
426       }
427 #else
428       void
429       insert(iterator __pos, size_type __n, const _Tp& __x)
430       {
431         __profcxx_vector2list_insert(this->_M_vect2list_info,
432                                      __pos.base() - _Base::begin(),
433                                      this->size());
434         size_type __old_size = this->capacity();
435         _Base::insert(__pos, __n, __x);
436         _M_profile_resize(__old_size, this->capacity());
437       }
438 #endif
440 #if __cplusplus >= 201103L
441       template<typename _InputIterator,
442                typename = std::_RequireInputIter<_InputIterator>>
443         iterator
444         insert(const_iterator __pos,
445                _InputIterator __first, _InputIterator __last)
446         {
447           __profcxx_vector2list_insert(this->_M_vect2list_info,
448                                        __pos.base() - _Base::cbegin(),
449                                        this->size());
450           size_type __old_size = this->capacity();
451           _Base_iterator __res = _Base::insert(__pos, __first, __last);
452           _M_profile_resize(__old_size, this->capacity());
453           return iterator(__res, this);
454         }
455 #else
456       template<typename _InputIterator>
457         void
458         insert(iterator __pos,
459                _InputIterator __first, _InputIterator __last)
460         {
461           __profcxx_vector2list_insert(this->_M_vect2list_info,
462                                        __pos.base() - _Base::begin(),
463                                        this->size());
464           size_type __old_size = this->capacity();
465           _Base::insert(__pos, __first, __last);
466           _M_profile_resize(__old_size, this->capacity());
467         }
468 #endif
470       iterator
471 #if __cplusplus >= 201103L
472       erase(const_iterator __pos)
473 #else
474       erase(iterator __pos)     
475 #endif
476       { return iterator(_Base::erase(__pos.base()), this); }
478       iterator
479 #if __cplusplus >= 201103L
480       erase(const_iterator __first, const_iterator __last)
481 #else
482       erase(iterator __first, iterator __last)
483 #endif
484       { return iterator(_Base::erase(__first.base(), __last.base()), this); }
486       void
487       clear() _GLIBCXX_NOEXCEPT
488       {
489         this->_M_profile_destruct();
490         _Base::clear();
491         this->_M_profile_construct();
492       }
494       inline void
495       _M_profile_iterate(int __rewind = 0) const
496       { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }
498     private:
499       void _M_profile_resize(size_type __old_size, size_type __new_size)
500       {
501         if (__old_size < __new_size)
502           {
503             __profcxx_vector_size_resize(this->_M_size_info,
504                                          this->size(), __new_size);
505             __profcxx_vector2list_resize(this->_M_vect2list_info,
506                                          this->size(), __new_size);
507           }
508       }
509     };
511   template<typename _Tp, typename _Alloc>
512     inline bool
513     operator==(const vector<_Tp, _Alloc>& __lhs,
514                const vector<_Tp, _Alloc>& __rhs)
515     { return __lhs._M_base() == __rhs._M_base(); }
517   template<typename _Tp, typename _Alloc>
518     inline bool
519     operator!=(const vector<_Tp, _Alloc>& __lhs,
520                const vector<_Tp, _Alloc>& __rhs)
521     { return __lhs._M_base() != __rhs._M_base(); }
523   template<typename _Tp, typename _Alloc>
524     inline bool
525     operator<(const vector<_Tp, _Alloc>& __lhs,
526               const vector<_Tp, _Alloc>& __rhs)
527     { return __lhs._M_base() < __rhs._M_base(); }
529   template<typename _Tp, typename _Alloc>
530     inline bool
531     operator<=(const vector<_Tp, _Alloc>& __lhs,
532                const vector<_Tp, _Alloc>& __rhs)
533     { return __lhs._M_base() <= __rhs._M_base(); }
535   template<typename _Tp, typename _Alloc>
536     inline bool
537     operator>=(const vector<_Tp, _Alloc>& __lhs,
538                const vector<_Tp, _Alloc>& __rhs)
539     { return __lhs._M_base() >= __rhs._M_base(); }
541   template<typename _Tp, typename _Alloc>
542     inline bool
543     operator>(const vector<_Tp, _Alloc>& __lhs,
544               const vector<_Tp, _Alloc>& __rhs)
545     { return __lhs._M_base() > __rhs._M_base(); }
547   template<typename _Tp, typename _Alloc>
548     inline void
549     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
550     { __lhs.swap(__rhs); }
552 #if __cplusplus >= 201103L
553   template<typename _Tp, typename _Alloc>
554     inline void
555     swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
556     { __lhs.swap(__rhs); }
558   template<typename _Tp, typename _Alloc>
559     inline void
560     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
561     { __lhs.swap(__rhs); }
562 #endif
564 } // namespace __profile
566 #if __cplusplus >= 201103L
567   // DR 1182.
568   /// std::hash specialization for vector<bool>.
569   template<typename _Alloc>
570     struct hash<__profile::vector<bool, _Alloc>>
571     : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
572     {
573       size_t
574       operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
575       {
576         return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b._M_base());
577       }
578     };
579 #endif
581 } // namespace std
583 #endif