]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/profile/vector
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / profile / vector
1 // Profiling vector implementation -*- C++ -*-
2
3 // Copyright (C) 2009-2018 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 _Vector>
41 class _Vector_profile_pre
42 {
43 _Vector&
44 _M_conjure()
45 { return *static_cast<_Vector*>(this); }
46
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;
52
53 _Vector_profile_pre&
54 operator=(const _Vector_profile_pre&)
55 { _M_conjure()._M_profile_destruct(); }
56
57 _Vector_profile_pre&
58 operator=(_Vector_profile_pre&&) noexcept
59 { _M_conjure()._M_profile_destruct(); }
60 #endif
61 };
62
63 template<typename _Vector>
64 class _Vector_profile_post
65 {
66 _Vector&
67 _M_conjure()
68 { return *static_cast<_Vector*>(this); }
69
70 protected:
71 __gnu_profile::__container_size_info* _M_size_info;
72 __gnu_profile::__vector2list_info* _M_vect2list_info;
73
74 _Vector_profile_post() _GLIBCXX_NOEXCEPT
75 { _M_profile_construct(); }
76
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); }
83
84 _Vector_profile_post&
85 operator=(const _Vector_profile_post&) noexcept
86 { _M_profile_construct(); }
87
88 _Vector_profile_post&
89 operator=(_Vector_profile_post&& __other) noexcept
90 {
91 _M_swap(__other);
92 __other._M_profile_construct();
93 }
94 #endif
95
96 ~_Vector_profile_post()
97 { _M_conjure()._M_profile_destruct(); }
98
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 }
107
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 }
118
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 };
126
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;
135
136 typedef typename _Base::iterator _Base_iterator;
137 typedef typename _Base::const_iterator _Base_const_iterator;
138
139 public:
140 typedef typename _Base::reference reference;
141 typedef typename _Base::const_reference const_reference;
142
143 typedef __iterator_tracker<_Base_iterator, vector>
144 iterator;
145 typedef __iterator_tracker<_Base_const_iterator, vector>
146 const_iterator;
147
148 typedef typename _Base::size_type size_type;
149 typedef typename _Base::difference_type difference_type;
150
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;
157
158 _Base&
159 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
160
161 const _Base&
162 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
163
164 // 23.2.4.1 construct/copy/destroy:
165
166 #if __cplusplus < 201103L
167 vector()
168 { }
169
170 vector(const vector& __x)
171 : _Base(__x) { }
172 #else
173 vector() = default;
174 vector(const vector&) = default;
175 vector(vector&&) = default;
176 #endif
177
178 explicit
179 vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
180 : _Base(__a) { }
181
182 #if __cplusplus >= 201103L
183 explicit
184 vector(size_type __n, const _Allocator& __a = _Allocator())
185 : _Base(__n, __a) { }
186
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
196
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) { }
206
207 /// Construction from a normal-mode vector
208 vector(const _Base& __x)
209 : _Base(__x) { }
210
211 #if __cplusplus >= 201103L
212 vector(const _Base& __x, const _Allocator& __a)
213 : _Base(__x, __a) { }
214
215 vector(vector&& __x, const _Allocator& __a)
216 : _Base(std::move(__x), __a) { }
217
218 vector(initializer_list<value_type> __l,
219 const allocator_type& __a = allocator_type())
220 : _Base(__l, __a) { }
221 #endif
222
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;
235
236 vector&
237 operator=(vector&&) = default;
238
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
248
249 // iterators:
250 iterator
251 begin() _GLIBCXX_NOEXCEPT
252 { return iterator(_Base::begin(), this); }
253
254 const_iterator
255 begin() const _GLIBCXX_NOEXCEPT
256 { return const_iterator(_Base::begin(), this); }
257
258 iterator
259 end() _GLIBCXX_NOEXCEPT
260 { return iterator(_Base::end(), this); }
261
262 const_iterator
263 end() const _GLIBCXX_NOEXCEPT
264 { return const_iterator(_Base::end(), this); }
265
266 reverse_iterator
267 rbegin() _GLIBCXX_NOEXCEPT
268 { return reverse_iterator(end()); }
269
270 const_reverse_iterator
271 rbegin() const _GLIBCXX_NOEXCEPT
272 { return const_reverse_iterator(end()); }
273
274 reverse_iterator
275 rend() _GLIBCXX_NOEXCEPT
276 { return reverse_iterator(begin()); }
277
278 const_reverse_iterator
279 rend() const _GLIBCXX_NOEXCEPT
280 { return const_reverse_iterator(begin()); }
281
282 #if __cplusplus >= 201103L
283 const_iterator
284 cbegin() const noexcept
285 { return const_iterator(_Base::begin(), this); }
286
287 const_iterator
288 cend() const noexcept
289 { return const_iterator(_Base::end(), this); }
290
291 const_reverse_iterator
292 crbegin() const noexcept
293 { return const_reverse_iterator(end()); }
294
295 const_reverse_iterator
296 crend() const noexcept
297 { return const_reverse_iterator(begin()); }
298 #endif
299
300 // 23.2.4.2 capacity:
301
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 }
310
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
327
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 }
341
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 }
350
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 }
359
360 #endif
361
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 }
377
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 }
390
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 }
399
400 iterator
401 insert(const_iterator __pos, initializer_list<value_type> __l)
402 { return this->insert(__pos, __l.begin(), __l.end()); }
403 #endif
404
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 }
414
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
439
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
469
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); }
477
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); }
485
486 void
487 clear() _GLIBCXX_NOEXCEPT
488 {
489 this->_M_profile_destruct();
490 _Base::clear();
491 this->_M_profile_construct();
492 }
493
494 inline void
495 _M_profile_iterate(int __rewind = 0) const
496 { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }
497
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 };
510
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(); }
516
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(); }
522
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(); }
528
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(); }
534
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(); }
540
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(); }
546
547 template<typename _Tp, typename _Alloc>
548 inline void
549 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
550 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
551 { __lhs.swap(__rhs); }
552
553 } // namespace __profile
554
555 #if __cplusplus >= 201103L
556 // DR 1182.
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>>
561 {
562 size_t
563 operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
564 {
565 return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b._M_base());
566 }
567 };
568 #endif
569
570 } // namespace std
571
572 #endif