Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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