1 // Profiling vector implementation -*- C++ -*-
3 // Copyright (C) 2009-2019 Free Software Foundation, Inc.
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)
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.
28 #ifndef _GLIBCXX_PROFILE_VECTOR
29 #define _GLIBCXX_PROFILE_VECTOR 1
33 #include <profile/base.h>
34 #include <profile/iterator_tracker.h>
36 namespace std _GLIBCXX_VISIBILITY(default)
40 template<typename _Vector>
41 class _Vector_profile_pre
45 { return *static_cast<_Vector*>(this); }
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;
54 operator=(const _Vector_profile_pre&)
55 { _M_conjure()._M_profile_destruct(); }
58 operator=(_Vector_profile_pre&&) noexcept
59 { _M_conjure()._M_profile_destruct(); }
63 template<typename _Vector>
64 class _Vector_profile_post
68 { return *static_cast<_Vector*>(this); }
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()
85 operator=(const _Vector_profile_post&) noexcept
86 { _M_profile_construct(); }
89 operator=(_Vector_profile_post&& __other) noexcept
92 __other._M_profile_construct();
96 ~_Vector_profile_post()
97 { _M_conjure()._M_profile_destruct(); }
101 _M_profile_construct() _GLIBCXX_NOEXCEPT
104 __profcxx_vector_size_construct(_M_conjure().capacity());
105 _M_vect2list_info = __profcxx_vector2list_construct();
109 _M_profile_destruct() _GLIBCXX_NOEXCEPT
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());
120 _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT
122 std::swap(_M_size_info, __other._M_size_info);
123 std::swap(_M_vect2list_info, __other._M_vect2list_info);
127 template<typename _Tp,
128 typename _Allocator = std::allocator<_Tp> >
130 : public _Vector_profile_pre<vector<_Tp, _Allocator> >,
131 public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
132 public _Vector_profile_post<vector<_Tp, _Allocator> >
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;
140 typedef typename _Base::reference reference;
141 typedef typename _Base::const_reference const_reference;
143 typedef __iterator_tracker<_Base_iterator, vector>
145 typedef __iterator_tracker<_Base_const_iterator, vector>
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;
159 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
162 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
164 // 23.2.4.1 construct/copy/destroy:
166 #if __cplusplus < 201103L
170 vector(const vector& __x)
174 vector(const vector&) = default;
175 vector(vector&&) = default;
179 vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
182 #if __cplusplus >= 201103L
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) { }
192 vector(size_type __n, const _Tp& __value = _Tp(),
193 const _Allocator& __a = _Allocator())
194 : _Base(__n, __value, __a) { }
197 #if __cplusplus >= 201103L
198 template<typename _InputIterator,
199 typename = std::_RequireInputIter<_InputIterator>>
201 template<typename _InputIterator>
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)
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) { }
223 #if __cplusplus < 201103L
225 operator=(const vector& __x)
227 this->_M_profile_destruct();
229 this->_M_profile_construct();
234 operator=(const vector&) = default;
237 operator=(vector&&) = default;
240 operator=(initializer_list<value_type> __l)
242 this->_M_profile_destruct();
244 this->_M_profile_construct();
251 begin() _GLIBCXX_NOEXCEPT
252 { return iterator(_Base::begin(), this); }
255 begin() const _GLIBCXX_NOEXCEPT
256 { return const_iterator(_Base::begin(), this); }
259 end() _GLIBCXX_NOEXCEPT
260 { return iterator(_Base::end(), this); }
263 end() const _GLIBCXX_NOEXCEPT
264 { return const_iterator(_Base::end(), this); }
267 rbegin() _GLIBCXX_NOEXCEPT
268 { return reverse_iterator(end()); }
270 const_reverse_iterator
271 rbegin() const _GLIBCXX_NOEXCEPT
272 { return const_reverse_iterator(end()); }
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
284 cbegin() const noexcept
285 { return const_iterator(_Base::begin(), this); }
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()); }
300 // 23.2.4.2 capacity:
302 #if __cplusplus >= 201103L
304 resize(size_type __sz)
306 __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
307 _M_profile_resize(this->capacity(), __sz);
312 resize(size_type __sz, const _Tp& __c)
314 __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
315 _M_profile_resize(this->capacity(), __sz);
316 _Base::resize(__sz, __c);
320 resize(size_type __sz, _Tp __c = _Tp())
322 __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
323 _M_profile_resize(this->capacity(), __sz);
324 _Base::resize(__sz, __c);
330 operator[](size_type __n) _GLIBCXX_NOEXCEPT
332 __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
333 return _M_base()[__n];
336 operator[](size_type __n) const _GLIBCXX_NOEXCEPT
338 __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
339 return _M_base()[__n];
342 // 23.2.4.3 modifiers:
344 push_back(const _Tp& __x)
346 size_type __old_size = this->capacity();
347 _Base::push_back(__x);
348 _M_profile_resize(__old_size, this->capacity());
351 #if __cplusplus >= 201103L
355 size_type __old_size = this->capacity();
356 _Base::push_back(std::move(__x));
357 _M_profile_resize(__old_size, this->capacity());
363 #if __cplusplus >= 201103L
364 insert(const_iterator __pos, const _Tp& __x)
366 insert(iterator __pos, const _Tp& __x)
369 __profcxx_vector2list_insert(this->_M_vect2list_info,
370 __pos.base() - _Base::begin(),
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);
378 #if __cplusplus >= 201103L
380 insert(const_iterator __pos, _Tp&& __x)
382 __profcxx_vector2list_insert(this->_M_vect2list_info,
383 __pos.base() - _Base::cbegin(),
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);
391 template<typename... _Args>
393 emplace(const_iterator __pos, _Args&&... __args)
395 _Base_iterator __res = _Base::emplace(__pos.base(),
396 std::forward<_Args>(__args)...);
397 return iterator(__res, this);
401 insert(const_iterator __pos, initializer_list<value_type> __l)
402 { return this->insert(__pos, __l.begin(), __l.end()); }
407 #if __cplusplus >= 201103L
408 noexcept( noexcept(declval<_Base>().swap(__x)) )
415 #if __cplusplus >= 201103L
417 insert(const_iterator __pos, size_type __n, const _Tp& __x)
419 __profcxx_vector2list_insert(this->_M_vect2list_info,
420 __pos.base() - _Base::cbegin(),
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);
429 insert(iterator __pos, size_type __n, const _Tp& __x)
431 __profcxx_vector2list_insert(this->_M_vect2list_info,
432 __pos.base() - _Base::begin(),
434 size_type __old_size = this->capacity();
435 _Base::insert(__pos, __n, __x);
436 _M_profile_resize(__old_size, this->capacity());
440 #if __cplusplus >= 201103L
441 template<typename _InputIterator,
442 typename = std::_RequireInputIter<_InputIterator>>
444 insert(const_iterator __pos,
445 _InputIterator __first, _InputIterator __last)
447 __profcxx_vector2list_insert(this->_M_vect2list_info,
448 __pos.base() - _Base::cbegin(),
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);
456 template<typename _InputIterator>
458 insert(iterator __pos,
459 _InputIterator __first, _InputIterator __last)
461 __profcxx_vector2list_insert(this->_M_vect2list_info,
462 __pos.base() - _Base::begin(),
464 size_type __old_size = this->capacity();
465 _Base::insert(__pos, __first, __last);
466 _M_profile_resize(__old_size, this->capacity());
471 #if __cplusplus >= 201103L
472 erase(const_iterator __pos)
474 erase(iterator __pos)
476 { return iterator(_Base::erase(__pos.base()), this); }
479 #if __cplusplus >= 201103L
480 erase(const_iterator __first, const_iterator __last)
482 erase(iterator __first, iterator __last)
484 { return iterator(_Base::erase(__first.base(), __last.base()), this); }
487 clear() _GLIBCXX_NOEXCEPT
489 this->_M_profile_destruct();
491 this->_M_profile_construct();
495 _M_profile_iterate(int __rewind = 0) const
496 { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }
499 void _M_profile_resize(size_type __old_size, size_type __new_size)
501 if (__old_size < __new_size)
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);
511 template<typename _Tp, typename _Alloc>
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>
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>
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>
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>
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>
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>
549 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
550 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
551 { __lhs.swap(__rhs); }
553 } // namespace __profile
555 #if __cplusplus >= 201103L
557 /// std::hash specialization for vector<bool>.
558 template<typename _Alloc>
559 struct hash<__profile::vector<bool, _Alloc>>
560 : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
563 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
565 return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b._M_base());