]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/debug/vector
re PR fortran/45439 ([OOP] SELECT TYPE bogus complaint about INTENT)
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / vector
CommitLineData
285b36d6
BK
1// Debugging vector implementation -*- C++ -*-
2
79667f82 3// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
285b36d6
BK
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
748086b7 9// Free Software Foundation; either version 3, or (at your option)
285b36d6
BK
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
748086b7
JJ
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
285b36d6 25
78a53887
BK
26/** @file debug/vector
27 * This file is a GNU debug extension to the Standard C++ Library.
28 */
29
285b36d6
BK
30#ifndef _GLIBCXX_DEBUG_VECTOR
31#define _GLIBCXX_DEBUG_VECTOR 1
32
33#include <vector>
d2763ab5 34#include <utility>
285b36d6
BK
35#include <debug/safe_sequence.h>
36#include <debug/safe_iterator.h>
37
3cbc7af0
BK
38namespace std
39{
45f388bb 40namespace __debug
285b36d6 41{
1ceb9e06 42 /// Class std::vector with safety/checking/debug instrumentation.
526da49c 43 template<typename _Tp,
285b36d6
BK
44 typename _Allocator = std::allocator<_Tp> >
45 class vector
c2ba9709 46 : public _GLIBCXX_STD_D::vector<_Tp, _Allocator>,
285b36d6
BK
47 public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
48 {
c2ba9709 49 typedef _GLIBCXX_STD_D::vector<_Tp, _Allocator> _Base;
285b36d6
BK
50 typedef __gnu_debug::_Safe_sequence<vector> _Safe_base;
51
52 typedef typename _Base::const_iterator _Base_const_iterator;
53 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
54
55 public:
56 typedef typename _Base::reference reference;
57 typedef typename _Base::const_reference const_reference;
58
526da49c 59 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector>
285b36d6
BK
60 iterator;
61 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
62 const_iterator;
63
64 typedef typename _Base::size_type size_type;
65 typedef typename _Base::difference_type difference_type;
66
526da49c
BI
67 typedef _Tp value_type;
68 typedef _Allocator allocator_type;
09952acc
PC
69 typedef typename _Base::pointer pointer;
70 typedef typename _Base::const_pointer const_pointer;
285b36d6
BK
71 typedef std::reverse_iterator<iterator> reverse_iterator;
72 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
73
74 // 23.2.4.1 construct/copy/destroy:
dc2cf706
PC
75 explicit
76 vector(const _Allocator& __a = _Allocator())
285b36d6
BK
77 : _Base(__a), _M_guaranteed_capacity(0) { }
78
dc2cf706
PC
79#ifdef __GXX_EXPERIMENTAL_CXX0X__
80 explicit
81 vector(size_type __n)
82 : _Base(__n), _M_guaranteed_capacity(__n) { }
83
84 vector(size_type __n, const _Tp& __value,
85 const _Allocator& __a = _Allocator())
285b36d6 86 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
dc2cf706
PC
87#else
88 explicit
89 vector(size_type __n, const _Tp& __value = _Tp(),
90 const _Allocator& __a = _Allocator())
91 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
92#endif
285b36d6
BK
93
94 template<class _InputIterator>
95 vector(_InputIterator __first, _InputIterator __last,
96 const _Allocator& __a = _Allocator())
526da49c 97 : _Base(__gnu_debug::__check_valid_range(__first, __last),
285b36d6
BK
98 __last, __a),
99 _M_guaranteed_capacity(0)
100 { _M_update_guaranteed_capacity(); }
101
ed540c0a 102 vector(const vector& __x)
285b36d6
BK
103 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
104
105 /// Construction from a release-mode vector
526da49c 106 vector(const _Base& __x)
285b36d6
BK
107 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
108
ed540c0a
CJ
109#ifdef __GXX_EXPERIMENTAL_CXX0X__
110 vector(vector&& __x)
5f1fd346 111 : _Base(std::move(__x)), _Safe_base(),
cc8c030d
PC
112 _M_guaranteed_capacity(this->size())
113 {
ed540c0a
CJ
114 this->_M_swap(__x);
115 __x._M_guaranteed_capacity = 0;
116 }
988499f4
JM
117
118 vector(initializer_list<value_type> __l,
119 const allocator_type& __a = allocator_type())
b798df05
PC
120 : _Base(__l, __a), _Safe_base(),
121 _M_guaranteed_capacity(__l.size()) { }
ed540c0a
CJ
122#endif
123
285b36d6
BK
124 ~vector() { }
125
ed540c0a
CJ
126 vector&
127 operator=(const vector& __x)
285b36d6
BK
128 {
129 static_cast<_Base&>(*this) = __x;
130 this->_M_invalidate_all();
131 _M_update_guaranteed_capacity();
132 return *this;
133 }
134
ed540c0a
CJ
135#ifdef __GXX_EXPERIMENTAL_CXX0X__
136 vector&
137 operator=(vector&& __x)
138 {
0462fd5e
PC
139 // NB: DR 1204.
140 // NB: DR 675.
141 clear();
142 swap(__x);
ed540c0a
CJ
143 return *this;
144 }
988499f4
JM
145
146 vector&
147 operator=(initializer_list<value_type> __l)
148 {
149 static_cast<_Base&>(*this) = __l;
150 this->_M_invalidate_all();
151 _M_update_guaranteed_capacity();
152 return *this;
153 }
ed540c0a
CJ
154#endif
155
285b36d6 156 template<typename _InputIterator>
526da49c 157 void
285b36d6
BK
158 assign(_InputIterator __first, _InputIterator __last)
159 {
160 __glibcxx_check_valid_range(__first, __last);
161 _Base::assign(__first, __last);
162 this->_M_invalidate_all();
163 _M_update_guaranteed_capacity();
164 }
165
526da49c 166 void
285b36d6
BK
167 assign(size_type __n, const _Tp& __u)
168 {
169 _Base::assign(__n, __u);
170 this->_M_invalidate_all();
171 _M_update_guaranteed_capacity();
172 }
173
988499f4
JM
174#ifdef __GXX_EXPERIMENTAL_CXX0X__
175 void
176 assign(initializer_list<value_type> __l)
177 {
178 _Base::assign(__l);
179 this->_M_invalidate_all();
180 _M_update_guaranteed_capacity();
181 }
182#endif
183
285b36d6
BK
184 using _Base::get_allocator;
185
186 // iterators:
526da49c
BI
187 iterator
188 begin()
285b36d6
BK
189 { return iterator(_Base::begin(), this); }
190
526da49c
BI
191 const_iterator
192 begin() const
285b36d6
BK
193 { return const_iterator(_Base::begin(), this); }
194
526da49c 195 iterator
285b36d6
BK
196 end()
197 { return iterator(_Base::end(), this); }
198
526da49c 199 const_iterator
285b36d6
BK
200 end() const
201 { return const_iterator(_Base::end(), this); }
202
526da49c
BI
203 reverse_iterator
204 rbegin()
285b36d6
BK
205 { return reverse_iterator(end()); }
206
526da49c 207 const_reverse_iterator
285b36d6
BK
208 rbegin() const
209 { return const_reverse_iterator(end()); }
210
526da49c
BI
211 reverse_iterator
212 rend()
285b36d6
BK
213 { return reverse_iterator(begin()); }
214
526da49c
BI
215 const_reverse_iterator
216 rend() const
285b36d6
BK
217 { return const_reverse_iterator(begin()); }
218
0cd50f89
PC
219#ifdef __GXX_EXPERIMENTAL_CXX0X__
220 const_iterator
221 cbegin() const
222 { return const_iterator(_Base::begin(), this); }
223
224 const_iterator
225 cend() const
226 { return const_iterator(_Base::end(), this); }
227
228 const_reverse_iterator
229 crbegin() const
230 { return const_reverse_iterator(end()); }
231
232 const_reverse_iterator
233 crend() const
234 { return const_reverse_iterator(begin()); }
235#endif
236
285b36d6
BK
237 // 23.2.4.2 capacity:
238 using _Base::size;
239 using _Base::max_size;
240
dc2cf706
PC
241#ifdef __GXX_EXPERIMENTAL_CXX0X__
242 void
243 resize(size_type __sz)
244 {
245 bool __realloc = _M_requires_reallocation(__sz);
246 if (__sz < this->size())
247 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
248 _Base::resize(__sz);
249 if (__realloc)
250 this->_M_invalidate_all();
251 _M_update_guaranteed_capacity();
252 }
253
254 void
255 resize(size_type __sz, const _Tp& __c)
256 {
257 bool __realloc = _M_requires_reallocation(__sz);
258 if (__sz < this->size())
259 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
260 _Base::resize(__sz, __c);
261 if (__realloc)
262 this->_M_invalidate_all();
263 _M_update_guaranteed_capacity();
264 }
265#else
526da49c 266 void
285b36d6
BK
267 resize(size_type __sz, _Tp __c = _Tp())
268 {
269 bool __realloc = _M_requires_reallocation(__sz);
270 if (__sz < this->size())
271 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
272 _Base::resize(__sz, __c);
273 if (__realloc)
274 this->_M_invalidate_all();
ddc962a4 275 _M_update_guaranteed_capacity();
285b36d6 276 }
dc2cf706 277#endif
285b36d6 278
79667f82
PC
279#ifdef __GXX_EXPERIMENTAL_CXX0X__
280 using _Base::shrink_to_fit;
281#endif
282
2028b66d
SS
283 size_type
284 capacity() const
285 {
286#ifdef _GLIBCXX_DEBUG_PEDANTIC
287 return _M_guaranteed_capacity;
288#else
289 return _Base::capacity();
290#endif
291 }
292
285b36d6
BK
293 using _Base::empty;
294
526da49c 295 void
285b36d6
BK
296 reserve(size_type __n)
297 {
298 bool __realloc = _M_requires_reallocation(__n);
299 _Base::reserve(__n);
300 if (__n > _M_guaranteed_capacity)
301 _M_guaranteed_capacity = __n;
302 if (__realloc)
303 this->_M_invalidate_all();
304 }
305
306 // element access:
526da49c 307 reference
285b36d6
BK
308 operator[](size_type __n)
309 {
310 __glibcxx_check_subscript(__n);
311 return _M_base()[__n];
312 }
313
526da49c 314 const_reference
285b36d6
BK
315 operator[](size_type __n) const
316 {
317 __glibcxx_check_subscript(__n);
318 return _M_base()[__n];
319 }
320
321 using _Base::at;
322
526da49c 323 reference
285b36d6
BK
324 front()
325 {
326 __glibcxx_check_nonempty();
327 return _Base::front();
328 }
329
526da49c 330 const_reference
285b36d6
BK
331 front() const
332 {
333 __glibcxx_check_nonempty();
334 return _Base::front();
335 }
336
526da49c 337 reference
285b36d6
BK
338 back()
339 {
340 __glibcxx_check_nonempty();
341 return _Base::back();
342 }
343
526da49c 344 const_reference
285b36d6
BK
345 back() const
346 {
347 __glibcxx_check_nonempty();
348 return _Base::back();
349 }
350
8b5f07a2
PC
351 // _GLIBCXX_RESOLVE_LIB_DEFECTS
352 // DR 464. Suggestion for new member functions in standard containers.
353 using _Base::data;
354
285b36d6 355 // 23.2.4.3 modifiers:
526da49c 356 void
285b36d6
BK
357 push_back(const _Tp& __x)
358 {
359 bool __realloc = _M_requires_reallocation(this->size() + 1);
360 _Base::push_back(__x);
361 if (__realloc)
362 this->_M_invalidate_all();
363 _M_update_guaranteed_capacity();
364 }
4dc3e453
PC
365
366#ifdef __GXX_EXPERIMENTAL_CXX0X__
77f376d9
PC
367 template<typename _Up = _Tp>
368 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
369 void>::__type
370 push_back(_Tp&& __x)
371 { emplace_back(std::move(__x)); }
4dc3e453 372
6eef7402
CJ
373 template<typename... _Args>
374 void
4dc3e453 375 emplace_back(_Args&&... __args)
6eef7402
CJ
376 {
377 bool __realloc = _M_requires_reallocation(this->size() + 1);
4dc3e453 378 _Base::emplace_back(std::forward<_Args>(__args)...);
6eef7402
CJ
379 if (__realloc)
380 this->_M_invalidate_all();
381 _M_update_guaranteed_capacity();
382 }
383#endif
285b36d6 384
526da49c 385 void
285b36d6
BK
386 pop_back()
387 {
388 __glibcxx_check_nonempty();
389 iterator __victim = end() - 1;
390 __victim._M_invalidate();
391 _Base::pop_back();
392 }
393
6eef7402
CJ
394#ifdef __GXX_EXPERIMENTAL_CXX0X__
395 template<typename... _Args>
396 iterator
0a485bae 397 emplace(iterator __position, _Args&&... __args)
6eef7402
CJ
398 {
399 __glibcxx_check_insert(__position);
400 bool __realloc = _M_requires_reallocation(this->size() + 1);
401 difference_type __offset = __position - begin();
402 typename _Base::iterator __res = _Base::emplace(__position.base(),
403 std::forward<_Args>(__args)...);
404 if (__realloc)
405 this->_M_invalidate_all();
406 else
407 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
408 _M_update_guaranteed_capacity();
409 return iterator(__res, this);
410 }
411#endif
412
526da49c 413 iterator
285b36d6
BK
414 insert(iterator __position, const _Tp& __x)
415 {
416 __glibcxx_check_insert(__position);
417 bool __realloc = _M_requires_reallocation(this->size() + 1);
418 difference_type __offset = __position - begin();
419 typename _Base::iterator __res = _Base::insert(__position.base(),__x);
420 if (__realloc)
421 this->_M_invalidate_all();
422 else
423 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
424 _M_update_guaranteed_capacity();
425 return iterator(__res, this);
426 }
427
6eef7402 428#ifdef __GXX_EXPERIMENTAL_CXX0X__
77f376d9
PC
429 template<typename _Up = _Tp>
430 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
431 iterator>::__type
432 insert(iterator __position, _Tp&& __x)
433 { return emplace(__position, std::move(__x)); }
988499f4
JM
434
435 void
436 insert(iterator __position, initializer_list<value_type> __l)
437 { this->insert(__position, __l.begin(), __l.end()); }
6eef7402
CJ
438#endif
439
526da49c 440 void
285b36d6
BK
441 insert(iterator __position, size_type __n, const _Tp& __x)
442 {
443 __glibcxx_check_insert(__position);
444 bool __realloc = _M_requires_reallocation(this->size() + __n);
445 difference_type __offset = __position - begin();
446 _Base::insert(__position.base(), __n, __x);
447 if (__realloc)
448 this->_M_invalidate_all();
449 else
450 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
451 _M_update_guaranteed_capacity();
452 }
453
454 template<class _InputIterator>
526da49c
BI
455 void
456 insert(iterator __position,
285b36d6
BK
457 _InputIterator __first, _InputIterator __last)
458 {
459 __glibcxx_check_insert_range(__position, __first, __last);
526da49c 460
285b36d6
BK
461 /* Hard to guess if invalidation will occur, because __last
462 - __first can't be calculated in all cases, so we just
463 punt here by checking if it did occur. */
464 typename _Base::iterator __old_begin = _M_base().begin();
465 difference_type __offset = __position - begin();
466 _Base::insert(__position.base(), __first, __last);
526da49c 467
285b36d6
BK
468 if (_M_base().begin() != __old_begin)
469 this->_M_invalidate_all();
470 else
471 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
472 _M_update_guaranteed_capacity();
473 }
526da49c
BI
474
475 iterator
285b36d6
BK
476 erase(iterator __position)
477 {
478 __glibcxx_check_erase(__position);
479 difference_type __offset = __position - begin();
480 typename _Base::iterator __res = _Base::erase(__position.base());
481 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
482 return iterator(__res, this);
483 }
484
526da49c 485 iterator
285b36d6
BK
486 erase(iterator __first, iterator __last)
487 {
488 // _GLIBCXX_RESOLVE_LIB_DEFECTS
489 // 151. can't currently clear() empty container
490 __glibcxx_check_erase_range(__first, __last);
526da49c 491
285b36d6 492 difference_type __offset = __first - begin();
526da49c 493 typename _Base::iterator __res = _Base::erase(__first.base(),
285b36d6
BK
494 __last.base());
495 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
496 return iterator(__res, this);
497 }
498
526da49c 499 void
ed540c0a 500 swap(vector& __x)
285b36d6
BK
501 {
502 _Base::swap(__x);
503 this->_M_swap(__x);
1b80d64a 504 std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
285b36d6
BK
505 }
506
526da49c 507 void
285b36d6
BK
508 clear()
509 {
510 _Base::clear();
511 this->_M_invalidate_all();
1b80d64a 512 _M_guaranteed_capacity = 0;
285b36d6
BK
513 }
514
526da49c 515 _Base&
285b36d6
BK
516 _M_base() { return *this; }
517
526da49c 518 const _Base&
285b36d6
BK
519 _M_base() const { return *this; }
520
521 private:
522 size_type _M_guaranteed_capacity;
523
526da49c 524 bool
285b36d6 525 _M_requires_reallocation(size_type __elements)
2028b66d 526 { return __elements > this->capacity(); }
526da49c
BI
527
528 void
285b36d6
BK
529 _M_update_guaranteed_capacity()
530 {
531 if (this->size() > _M_guaranteed_capacity)
532 _M_guaranteed_capacity = this->size();
533 }
534 };
535
536 template<typename _Tp, typename _Alloc>
537 inline bool
538 operator==(const vector<_Tp, _Alloc>& __lhs,
539 const vector<_Tp, _Alloc>& __rhs)
540 { return __lhs._M_base() == __rhs._M_base(); }
541
542 template<typename _Tp, typename _Alloc>
543 inline bool
526da49c 544 operator!=(const vector<_Tp, _Alloc>& __lhs,
285b36d6
BK
545 const vector<_Tp, _Alloc>& __rhs)
546 { return __lhs._M_base() != __rhs._M_base(); }
547
548 template<typename _Tp, typename _Alloc>
549 inline bool
526da49c 550 operator<(const vector<_Tp, _Alloc>& __lhs,
285b36d6
BK
551 const vector<_Tp, _Alloc>& __rhs)
552 { return __lhs._M_base() < __rhs._M_base(); }
553
554 template<typename _Tp, typename _Alloc>
555 inline bool
526da49c 556 operator<=(const vector<_Tp, _Alloc>& __lhs,
285b36d6
BK
557 const vector<_Tp, _Alloc>& __rhs)
558 { return __lhs._M_base() <= __rhs._M_base(); }
559
560 template<typename _Tp, typename _Alloc>
561 inline bool
526da49c 562 operator>=(const vector<_Tp, _Alloc>& __lhs,
285b36d6
BK
563 const vector<_Tp, _Alloc>& __rhs)
564 { return __lhs._M_base() >= __rhs._M_base(); }
565
566 template<typename _Tp, typename _Alloc>
567 inline bool
526da49c 568 operator>(const vector<_Tp, _Alloc>& __lhs,
285b36d6
BK
569 const vector<_Tp, _Alloc>& __rhs)
570 { return __lhs._M_base() > __rhs._M_base(); }
571
572 template<typename _Tp, typename _Alloc>
573 inline void
574 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
575 { __lhs.swap(__rhs); }
ed540c0a 576
45f388bb 577} // namespace __debug
4cd533a7
PC
578
579#ifdef __GXX_EXPERIMENTAL_CXX0X__
580 // DR 1182.
581 /// std::hash specialization for vector<bool>.
582 template<typename _Alloc>
583 struct hash<__debug::vector<bool, _Alloc>>
95addb1b 584 : public std::unary_function<__debug::vector<bool, _Alloc>, size_t>
4cd533a7
PC
585 {
586 size_t
95addb1b 587 operator()(const __debug::vector<bool, _Alloc>& __b) const
4cd533a7
PC
588 { return std::hash<_GLIBCXX_STD_D::vector<bool, _Alloc>>()
589 (__b._M_base()); }
590 };
591#endif
592
3cbc7af0 593} // namespace std
285b36d6 594
526da49c 595#endif