]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/debug/deque
PR libstdc++/36104 part four
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / deque
CommitLineData
285b36d6
BK
1// Debugging deque 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/deque
27 * This file is a GNU debug extension to the Standard C++ Library.
28 */
29
285b36d6
BK
30#ifndef _GLIBCXX_DEBUG_DEQUE
31#define _GLIBCXX_DEBUG_DEQUE 1
32
33#include <deque>
34#include <debug/safe_sequence.h>
35#include <debug/safe_iterator.h>
36
12ffa228 37namespace std _GLIBCXX_VISIBILITY(default)
3cbc7af0 38{
45f388bb 39namespace __debug
285b36d6 40{
1ceb9e06 41 /// Class std::deque with safety/checking/debug instrumentation.
285b36d6 42 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
526da49c 43 class deque
12ffa228 44 : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>,
390e4c0d 45 public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
285b36d6 46 {
12ffa228 47 typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
285b36d6
BK
48 typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
49
afe96d41
FD
50 typedef typename _Base::const_iterator _Base_const_iterator;
51 typedef typename _Base::iterator _Base_iterator;
52 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
285b36d6 53 public:
09952acc
PC
54 typedef typename _Base::reference reference;
55 typedef typename _Base::const_reference const_reference;
526da49c 56
afe96d41 57 typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque>
526da49c 58 iterator;
afe96d41
FD
59 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque>
60 const_iterator;
526da49c 61
285b36d6
BK
62 typedef typename _Base::size_type size_type;
63 typedef typename _Base::difference_type difference_type;
526da49c
BI
64
65 typedef _Tp value_type;
66 typedef _Allocator allocator_type;
09952acc
PC
67 typedef typename _Base::pointer pointer;
68 typedef typename _Base::const_pointer const_pointer;
285b36d6
BK
69 typedef std::reverse_iterator<iterator> reverse_iterator;
70 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
71
72 // 23.2.1.1 construct/copy/destroy:
dc2cf706
PC
73 explicit
74 deque(const _Allocator& __a = _Allocator())
285b36d6
BK
75 : _Base(__a) { }
76
dc2cf706
PC
77#ifdef __GXX_EXPERIMENTAL_CXX0X__
78 explicit
79 deque(size_type __n)
80 : _Base(__n) { }
81
82 deque(size_type __n, const _Tp& __value,
83 const _Allocator& __a = _Allocator())
84 : _Base(__n, __value, __a) { }
85#else
86 explicit
87 deque(size_type __n, const _Tp& __value = _Tp(),
88 const _Allocator& __a = _Allocator())
285b36d6 89 : _Base(__n, __value, __a) { }
dc2cf706 90#endif
285b36d6
BK
91
92 template<class _InputIterator>
93 deque(_InputIterator __first, _InputIterator __last,
94 const _Allocator& __a = _Allocator())
1f5ca1a1
PC
95 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
96 __last)),
97 __gnu_debug::__base(__last), __a)
285b36d6
BK
98 { }
99
ed540c0a
CJ
100 deque(const deque& __x)
101 : _Base(__x), _Safe_base() { }
285b36d6 102
ed540c0a
CJ
103 deque(const _Base& __x)
104 : _Base(__x), _Safe_base() { }
105
106#ifdef __GXX_EXPERIMENTAL_CXX0X__
107 deque(deque&& __x)
5f1fd346 108 : _Base(std::move(__x)), _Safe_base()
ed540c0a 109 { this->_M_swap(__x); }
988499f4
JM
110
111 deque(initializer_list<value_type> __l,
112 const allocator_type& __a = allocator_type())
113 : _Base(__l, __a), _Safe_base() { }
ed540c0a 114#endif
526da49c 115
285b36d6 116 ~deque() { }
526da49c 117
ed540c0a
CJ
118 deque&
119 operator=(const deque& __x)
285b36d6
BK
120 {
121 *static_cast<_Base*>(this) = __x;
122 this->_M_invalidate_all();
123 return *this;
124 }
526da49c 125
ed540c0a
CJ
126#ifdef __GXX_EXPERIMENTAL_CXX0X__
127 deque&
128 operator=(deque&& __x)
129 {
0462fd5e
PC
130 // NB: DR 1204.
131 // NB: DR 675.
132 clear();
133 swap(__x);
ed540c0a
CJ
134 return *this;
135 }
988499f4
JM
136
137 deque&
138 operator=(initializer_list<value_type> __l)
139 {
140 *static_cast<_Base*>(this) = __l;
141 this->_M_invalidate_all();
142 return *this;
143 }
ed540c0a
CJ
144#endif
145
285b36d6 146 template<class _InputIterator>
526da49c 147 void
285b36d6
BK
148 assign(_InputIterator __first, _InputIterator __last)
149 {
150 __glibcxx_check_valid_range(__first, __last);
1f5ca1a1
PC
151 _Base::assign(__gnu_debug::__base(__first),
152 __gnu_debug::__base(__last));
285b36d6
BK
153 this->_M_invalidate_all();
154 }
155
526da49c 156 void
285b36d6
BK
157 assign(size_type __n, const _Tp& __t)
158 {
159 _Base::assign(__n, __t);
160 this->_M_invalidate_all();
161 }
526da49c 162
988499f4
JM
163#ifdef __GXX_EXPERIMENTAL_CXX0X__
164 void
165 assign(initializer_list<value_type> __l)
166 {
167 _Base::assign(__l);
168 this->_M_invalidate_all();
169 }
170#endif
171
285b36d6 172 using _Base::get_allocator;
526da49c 173
285b36d6 174 // iterators:
526da49c
BI
175 iterator
176 begin()
285b36d6 177 { return iterator(_Base::begin(), this); }
526da49c
BI
178
179 const_iterator
180 begin() const
285b36d6 181 { return const_iterator(_Base::begin(), this); }
526da49c
BI
182
183 iterator
184 end()
285b36d6 185 { return iterator(_Base::end(), this); }
526da49c
BI
186
187 const_iterator
188 end() const
285b36d6 189 { return const_iterator(_Base::end(), this); }
526da49c
BI
190
191 reverse_iterator
192 rbegin()
285b36d6 193 { return reverse_iterator(end()); }
526da49c
BI
194
195 const_reverse_iterator
285b36d6
BK
196 rbegin() const
197 { return const_reverse_iterator(end()); }
526da49c
BI
198
199 reverse_iterator
200 rend()
285b36d6 201 { return reverse_iterator(begin()); }
526da49c
BI
202
203 const_reverse_iterator
285b36d6
BK
204 rend() const
205 { return const_reverse_iterator(begin()); }
526da49c 206
0cd50f89
PC
207#ifdef __GXX_EXPERIMENTAL_CXX0X__
208 const_iterator
209 cbegin() const
210 { return const_iterator(_Base::begin(), this); }
211
212 const_iterator
213 cend() const
214 { return const_iterator(_Base::end(), this); }
215
216 const_reverse_iterator
217 crbegin() const
218 { return const_reverse_iterator(end()); }
219
220 const_reverse_iterator
221 crend() const
222 { return const_reverse_iterator(begin()); }
223#endif
224
afe96d41
FD
225 private:
226 void
227 _M_invalidate_after_nth(difference_type __n)
228 {
229 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
230 this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
231 }
232
233 public:
285b36d6
BK
234 // 23.2.1.2 capacity:
235 using _Base::size;
236 using _Base::max_size;
526da49c 237
dc2cf706
PC
238#ifdef __GXX_EXPERIMENTAL_CXX0X__
239 void
240 resize(size_type __sz)
241 {
dc2cf706
PC
242 bool __invalidate_all = __sz > this->size();
243 if (__sz < this->size())
afe96d41 244 this->_M_invalidate_after_nth(__sz);
dc2cf706
PC
245
246 _Base::resize(__sz);
247
248 if (__invalidate_all)
249 this->_M_invalidate_all();
250 }
251
252 void
253 resize(size_type __sz, const _Tp& __c)
254 {
dc2cf706
PC
255 bool __invalidate_all = __sz > this->size();
256 if (__sz < this->size())
afe96d41 257 this->_M_invalidate_after_nth(__sz);
dc2cf706
PC
258
259 _Base::resize(__sz, __c);
260
261 if (__invalidate_all)
262 this->_M_invalidate_all();
263 }
264#else
526da49c 265 void
285b36d6
BK
266 resize(size_type __sz, _Tp __c = _Tp())
267 {
285b36d6
BK
268 bool __invalidate_all = __sz > this->size();
269 if (__sz < this->size())
afe96d41 270 this->_M_invalidate_after_nth(__sz);
526da49c 271
285b36d6 272 _Base::resize(__sz, __c);
526da49c 273
285b36d6
BK
274 if (__invalidate_all)
275 this->_M_invalidate_all();
276 }
dc2cf706 277#endif
526da49c 278
79667f82
PC
279#ifdef __GXX_EXPERIMENTAL_CXX0X__
280 using _Base::shrink_to_fit;
281#endif
282
285b36d6 283 using _Base::empty;
526da49c 284
285b36d6 285 // element access:
526da49c 286 reference
285b36d6
BK
287 operator[](size_type __n)
288 {
289 __glibcxx_check_subscript(__n);
290 return _M_base()[__n];
291 }
526da49c
BI
292
293 const_reference
285b36d6
BK
294 operator[](size_type __n) const
295 {
296 __glibcxx_check_subscript(__n);
297 return _M_base()[__n];
298 }
526da49c 299
285b36d6 300 using _Base::at;
526da49c
BI
301
302 reference
285b36d6
BK
303 front()
304 {
305 __glibcxx_check_nonempty();
306 return _Base::front();
307 }
526da49c
BI
308
309 const_reference
285b36d6
BK
310 front() const
311 {
312 __glibcxx_check_nonempty();
313 return _Base::front();
314 }
526da49c
BI
315
316 reference
285b36d6
BK
317 back()
318 {
319 __glibcxx_check_nonempty();
320 return _Base::back();
321 }
526da49c
BI
322
323 const_reference
285b36d6
BK
324 back() const
325 {
326 __glibcxx_check_nonempty();
327 return _Base::back();
328 }
526da49c 329
285b36d6 330 // 23.2.1.3 modifiers:
526da49c 331 void
285b36d6
BK
332 push_front(const _Tp& __x)
333 {
334 _Base::push_front(__x);
335 this->_M_invalidate_all();
336 }
526da49c
BI
337
338 void
285b36d6
BK
339 push_back(const _Tp& __x)
340 {
341 _Base::push_back(__x);
342 this->_M_invalidate_all();
343 }
4dc3e453
PC
344
345#ifdef __GXX_EXPERIMENTAL_CXX0X__
346 void
347 push_front(_Tp&& __x)
348 { emplace_front(std::move(__x)); }
349
350 void
351 push_back(_Tp&& __x)
352 { emplace_back(std::move(__x)); }
353
7ffec97f
CJ
354 template<typename... _Args>
355 void
4dc3e453 356 emplace_front(_Args&&... __args)
7ffec97f 357 {
4dc3e453 358 _Base::emplace_front(std::forward<_Args>(__args)...);
7ffec97f
CJ
359 this->_M_invalidate_all();
360 }
361
362 template<typename... _Args>
363 void
4dc3e453 364 emplace_back(_Args&&... __args)
7ffec97f 365 {
4dc3e453 366 _Base::emplace_back(std::forward<_Args>(__args)...);
7ffec97f
CJ
367 this->_M_invalidate_all();
368 }
369
370 template<typename... _Args>
371 iterator
372 emplace(iterator __position, _Args&&... __args)
373 {
374 __glibcxx_check_insert(__position);
afe96d41
FD
375 _Base_iterator __res = _Base::emplace(__position.base(),
376 std::forward<_Args>(__args)...);
7ffec97f
CJ
377 this->_M_invalidate_all();
378 return iterator(__res, this);
379 }
380#endif
526da49c
BI
381
382 iterator
285b36d6
BK
383 insert(iterator __position, const _Tp& __x)
384 {
385 __glibcxx_check_insert(__position);
afe96d41 386 _Base_iterator __res = _Base::insert(__position.base(), __x);
285b36d6
BK
387 this->_M_invalidate_all();
388 return iterator(__res, this);
389 }
526da49c 390
7ffec97f
CJ
391#ifdef __GXX_EXPERIMENTAL_CXX0X__
392 iterator
393 insert(iterator __position, _Tp&& __x)
360b7bff 394 { return emplace(__position, std::move(__x)); }
988499f4
JM
395
396 void
397 insert(iterator __p, initializer_list<value_type> __l)
398 {
399 _Base::insert(__p, __l);
400 this->_M_invalidate_all();
401 }
7ffec97f
CJ
402#endif
403
526da49c 404 void
285b36d6
BK
405 insert(iterator __position, size_type __n, const _Tp& __x)
406 {
407 __glibcxx_check_insert(__position);
408 _Base::insert(__position.base(), __n, __x);
409 this->_M_invalidate_all();
410 }
526da49c 411
285b36d6 412 template<class _InputIterator>
526da49c
BI
413 void
414 insert(iterator __position,
285b36d6
BK
415 _InputIterator __first, _InputIterator __last)
416 {
417 __glibcxx_check_insert_range(__position, __first, __last);
1f5ca1a1
PC
418 _Base::insert(__position.base(), __gnu_debug::__base(__first),
419 __gnu_debug::__base(__last));
285b36d6
BK
420 this->_M_invalidate_all();
421 }
526da49c
BI
422
423 void
285b36d6
BK
424 pop_front()
425 {
426 __glibcxx_check_nonempty();
afe96d41 427 this->_M_invalidate_if(_Equal(_Base::begin()));
285b36d6
BK
428 _Base::pop_front();
429 }
526da49c
BI
430
431 void
285b36d6
BK
432 pop_back()
433 {
434 __glibcxx_check_nonempty();
afe96d41 435 this->_M_invalidate_if(_Equal(--_Base::end()));
285b36d6
BK
436 _Base::pop_back();
437 }
526da49c
BI
438
439 iterator
285b36d6
BK
440 erase(iterator __position)
441 {
442 __glibcxx_check_erase(__position);
afe96d41
FD
443 _Base_iterator __victim = __position.base();
444 if (__victim == _Base::begin() || __victim == _Base::end()-1)
285b36d6 445 {
afe96d41
FD
446 this->_M_invalidate_if(_Equal(__victim));
447 return iterator(_Base::erase(__victim), this);
285b36d6
BK
448 }
449 else
450 {
afe96d41 451 _Base_iterator __res = _Base::erase(__victim);
285b36d6
BK
452 this->_M_invalidate_all();
453 return iterator(__res, this);
454 }
455 }
526da49c
BI
456
457 iterator
285b36d6
BK
458 erase(iterator __first, iterator __last)
459 {
460 // _GLIBCXX_RESOLVE_LIB_DEFECTS
461 // 151. can't currently clear() empty container
462 __glibcxx_check_erase_range(__first, __last);
afe96d41 463 if (__first.base() == _Base::begin() || __last.base() == _Base::end())
285b36d6
BK
464 {
465 this->_M_detach_singular();
afe96d41
FD
466 for (_Base_iterator __position = __first.base();
467 __position != __last.base(); ++__position)
285b36d6 468 {
afe96d41 469 this->_M_invalidate_if(_Equal(__position));
285b36d6 470 }
bc2631e0 471 __try
526da49c 472 {
285b36d6 473 return iterator(_Base::erase(__first.base(), __last.base()),
526da49c 474 this);
285b36d6 475 }
bc2631e0 476 __catch(...)
285b36d6
BK
477 {
478 this->_M_revalidate_singular();
479 __throw_exception_again;
480 }
481 }
482 else
483 {
afe96d41
FD
484 _Base_iterator __res = _Base::erase(__first.base(),
485 __last.base());
285b36d6
BK
486 this->_M_invalidate_all();
487 return iterator(__res, this);
488 }
489 }
526da49c
BI
490
491 void
ed540c0a 492 swap(deque& __x)
285b36d6
BK
493 {
494 _Base::swap(__x);
495 this->_M_swap(__x);
496 }
526da49c
BI
497
498 void
285b36d6
BK
499 clear()
500 {
501 _Base::clear();
502 this->_M_invalidate_all();
503 }
526da49c
BI
504
505 _Base&
285b36d6
BK
506 _M_base() { return *this; }
507
526da49c 508 const _Base&
285b36d6
BK
509 _M_base() const { return *this; }
510 };
511
512 template<typename _Tp, typename _Alloc>
513 inline bool
526da49c 514 operator==(const deque<_Tp, _Alloc>& __lhs,
285b36d6
BK
515 const deque<_Tp, _Alloc>& __rhs)
516 { return __lhs._M_base() == __rhs._M_base(); }
517
518 template<typename _Tp, typename _Alloc>
519 inline bool
526da49c 520 operator!=(const deque<_Tp, _Alloc>& __lhs,
285b36d6
BK
521 const deque<_Tp, _Alloc>& __rhs)
522 { return __lhs._M_base() != __rhs._M_base(); }
523
524 template<typename _Tp, typename _Alloc>
525 inline bool
ed540c0a
CJ
526 operator<(const deque<_Tp, _Alloc>& __lhs,
527 const deque<_Tp, _Alloc>& __rhs)
285b36d6
BK
528 { return __lhs._M_base() < __rhs._M_base(); }
529
530 template<typename _Tp, typename _Alloc>
531 inline bool
526da49c 532 operator<=(const deque<_Tp, _Alloc>& __lhs,
285b36d6
BK
533 const deque<_Tp, _Alloc>& __rhs)
534 { return __lhs._M_base() <= __rhs._M_base(); }
535
536 template<typename _Tp, typename _Alloc>
537 inline bool
526da49c 538 operator>=(const deque<_Tp, _Alloc>& __lhs,
285b36d6
BK
539 const deque<_Tp, _Alloc>& __rhs)
540 { return __lhs._M_base() >= __rhs._M_base(); }
541
542 template<typename _Tp, typename _Alloc>
543 inline bool
ed540c0a
CJ
544 operator>(const deque<_Tp, _Alloc>& __lhs,
545 const deque<_Tp, _Alloc>& __rhs)
285b36d6
BK
546 { return __lhs._M_base() > __rhs._M_base(); }
547
548 template<typename _Tp, typename _Alloc>
549 inline void
550 swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
551 { __lhs.swap(__rhs); }
ed540c0a 552
45f388bb 553} // namespace __debug
3cbc7af0 554} // namespace std
285b36d6
BK
555
556#endif