1
/*
2
 *
3
 * Copyright (c) 1994
4
 * Hewlett-Packard Company
5
 *
6
 * Copyright (c) 1996,1997
7
 * Silicon Graphics Computer Systems, Inc.
8
 *
9
 * Copyright (c) 1997
10
 * Moscow Center for SPARC Technology
11
 *
12
 * Copyright (c) 1999
13
 * Boris Fomitchev
14
 *
15
 * This material is provided "as is", with absolutely no warranty expressed
16
 * or implied. Any use is at your own risk.
17
 *
18
 * Permission to use or copy this software for any purpose is hereby granted
19
 * without fee, provided the above notices are retained on all copies.
20
 * Permission to modify the code and to distribute modified code is granted,
21
 * provided the above notices are retained, and a notice that the code was
22
 * modified is included with the above copyright notice.
23
 *
24
 */
25
26
#ifndef _STLP_DEQUE
27
#  define _STLP_DEQUE
28
29
#ifndef _STLP_OUTERMOST_HEADER_ID
30
#  define _STLP_OUTERMOST_HEADER_ID 0x22
31
#  include <stl/_prolog.h>
32
#endif
33
34
#ifndef _STLP_INTERNAL_ALGOBASE_H
35
#  include <stl/_algobase.h>
36
#endif
37
38
#ifndef _STLP_INTERNAL_ALLOC_H
39
#  include <stl/_alloc.h>
40
#endif
41
42
#ifndef _STLP_INTERNAL_ITERATOR_H
43
#  include <stl/_iterator.h>
44
#endif
45
46
#ifndef _STLP_INTERNAL_UNINITIALIZED_H
47
#  include <stl/_uninitialized.h>
48
#endif
49
50
#ifndef _STLP_RANGE_ERRORS_H
51
#  include <stl/_range_errors.h>
52
#endif
53
54
/* Class invariants:
55
 *  For any nonsingular iterator i:
56
 *    i.node is the address of an element in the map array.  The
57
 *      contents of i.node is a pointer to the beginning of a node.
58
 *    i.first == *(i.node)
59
 *    i.last  == i.first + node_size
60
 *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
61
 *      the implication of this is that i.cur is always a dereferenceable
62
 *      pointer, even if i is a past-the-end iterator.
63
 *  Start and Finish are always nonsingular iterators.  NOTE: this means
64
 *    that an empty deque must have one node, and that a deque
65
 *    with N elements, where N is the buffer size, must have two nodes.
66
 *  For every node other than start.node and finish.node, every element
67
 *    in the node is an initialized object.  If start.node == finish.node,
68
 *    then [start.cur, finish.cur) are initialized objects, and
69
 *    the elements outside that range are uninitialized storage.  Otherwise,
70
 *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
71
 *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
72
 *    are uninitialized storage.
73
 *  [map, map + map_size) is a valid, non-empty range.
74
 *  [start.node, finish.node] is a valid range contained within
75
 *    [map, map + map_size).
76
 *  A pointer in the range [map, map + map_size) points to an allocated node
77
 *    if and only if the pointer is in the range [start.node, finish.node].
78
 */
79
80
_STLP_BEGIN_NAMESPACE
81
82
_STLP_MOVE_TO_PRIV_NAMESPACE
83
84
template <class _Tp>
85
struct _Deque_iterator_base
86
{
87
    static size_t _S_buffer_size()
88
      {
89
        const size_t blocksize = _MAX_BYTES;
90
        return (sizeof(_Tp) < blocksize ? (blocksize / sizeof(_Tp)) : 1);
91
      }
92
93
    typedef random_access_iterator_tag iterator_category;
94
95
    typedef typename remove_const<_Tp>::type value_type;
96
    typedef size_t size_type;
97
    typedef ptrdiff_t difference_type;
98
99
    typedef value_type** _Map_pointer;
100
101
    value_type* _M_cur;
102
    value_type* _M_first;
103
    value_type* _M_last;
104
    _Map_pointer _M_node;
105
106
    _Deque_iterator_base( value_type* __x, _Map_pointer __y ) :
107
        _M_cur(__x),
108
        _M_first(*__y),
109
        _M_last(*__y + _S_buffer_size()),
110
        _M_node(__y)
111
      { }
112
113
    _Deque_iterator_base() :
114
        _M_cur(0),
115
        _M_first(0),
116
        _M_last(0),
117
        _M_node(0)
118
      { }
119
120
// see comment in doc/README.evc4 and doc/README.evc8
121
#if defined (_STLP_MSVC) && (_STLP_MSVC <= 1401) && defined (MIPS) && defined (NDEBUG)
122
    _Deque_iterator_base(_Deque_iterator_base const& __other) :
123
        _M_cur(__other._M_cur),
124
        _M_first(__other._M_first),
125
        _M_last(__other._M_last),
126
        _M_node(__other._M_node)
127
      { }
128
#endif
129
130
    difference_type _M_subtract( const _Deque_iterator_base& __x ) const
131
      {
132
        return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
133
          (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
134
      }
135
136
    void _M_increment()
137
      {
138
        if ( ++_M_cur == _M_last ) {
139
          _M_set_node( _M_node + 1 );
140
          _M_cur = _M_first;
141
        }
142
      }
143
144
    void _M_decrement()
145
      {
146
        if ( _M_cur == _M_first ) {
147
          _M_set_node( _M_node - 1 );
148
          _M_cur = _M_last;
149
        }
150
        --_M_cur;
151
      }
152
153
    void _M_advance( difference_type __n )
154
      {
155
        const size_t buffersize = _S_buffer_size();
156
        difference_type __offset = __n + (_M_cur - _M_first);
157
        if ( __offset >= 0 && __offset < difference_type(buffersize) ) {
158
          _M_cur += __n;
159
        } else {
160
          difference_type __node_offset = __offset > 0 ? __offset / buffersize
161
            : -difference_type((-__offset - 1) / buffersize) - 1;
162
          _M_set_node(_M_node + __node_offset);
163
          _M_cur = _M_first + (__offset - __node_offset * difference_type(buffersize));
164
        }
165
      }
166
167
    void _M_set_node( _Map_pointer __new_node )
168
      { _M_last = (_M_first = *(_M_node = __new_node)) + difference_type(_S_buffer_size()); }
169
};
170
171
template <class _Tp> struct _Deque_iterator;
172
template <class _Tp> struct _Deque_iterator<_Tp const>;
173
174
template <class _Tp>
175
struct _Deque_iterator :
176
    public _Deque_iterator_base<_Tp>
177
{
178
    typedef typename remove_const<_Tp>::type value_type;
179
    typedef value_type* pointer;
180
    typedef value_type& reference;
181
    typedef random_access_iterator_tag iterator_category;
182
    typedef size_t size_type;
183
    typedef ptrdiff_t difference_type;
184
    typedef value_type** _Map_pointer;
185
186
    typedef _Deque_iterator_base<_Tp> _Base;
187
    typedef _Deque_iterator<_Tp> _Self;
188
189
    _Deque_iterator( value_type* __x, _Map_pointer __y ) :
190
        _Deque_iterator_base<value_type>(__x,__y)
191
      { }
192
193
    _Deque_iterator()
194
      { }
195
196
    _Deque_iterator( const _Deque_iterator& ) = default;
197
    _Deque_iterator( _Deque_iterator&& ) = default;
198
199
    _Deque_iterator& operator =( const _Deque_iterator& ) = default;
200
201
    reference operator *() const
202
      { return *this->_M_cur; }
203
204
    const pointer operator ->() const
205
      { return &*this->_M_cur; }
206
207
    difference_type operator -( const _Deque_iterator& __x ) const
208
      { return this->_M_subtract(__x); }
209
    difference_type operator -( const _Deque_iterator<_Tp const>& __x ) const
210
      { return this->_M_subtract(__x); }
211
212
    _Self& operator ++()
213
      { this->_M_increment(); return *this; }
214
    _Self operator++(int)
215
      {
216
        _Self __tmp = *this;
217
        ++*this;
218
        return __tmp;
219
      }
220
221
    _Self& operator --()
222
      { this->_M_decrement(); return *this; }
223
    _Self operator--(int)
224
      {
225
        _Self __tmp = *this;
226
        --*this;
227
        return __tmp;
228
      }
229
230
    _Self& operator +=(difference_type __n)
231
      { this->_M_advance(__n); return *this; }
232
    _Self operator+(difference_type __n) const
233
      {
234
        _Self __tmp = *this;
235
        return __tmp += __n;
236
      }
237
238
    _Self& operator -=(difference_type __n)
239
      { return *this += -__n; }
240
    _Self operator -(difference_type __n) const
241
      {
242
        _Self __tmp = *this;
243
        return __tmp -= __n;
244
      }
245
246
    reference operator [](difference_type __n) const
247
      { return *(*this + __n); }
248
};
249
250
template <class _Tp>
251
struct _Deque_iterator<_Tp const> :
252
    public _Deque_iterator_base<_Tp>
253
{
254
    typedef _Tp value_type;
255
    typedef value_type const* pointer;
256
    typedef value_type const& reference;
257
    typedef random_access_iterator_tag iterator_category;
258
    typedef size_t size_type;
259
    typedef ptrdiff_t difference_type;
260
    typedef value_type** _Map_pointer;
261
262
    typedef _Deque_iterator_base<value_type const> _Base;
263
    typedef _Deque_iterator<value_type const> _Self;
264
265
    _Deque_iterator( value_type* __x, _Map_pointer __y ) :
266
        _Deque_iterator_base<value_type>(__x,__y)
267
      { }
268
269
    _Deque_iterator()
270
      { }
271
272
    _Deque_iterator( const _Deque_iterator& ) = default;
273
    _Deque_iterator( _Deque_iterator&& ) = default;
274
    _Deque_iterator( const _Deque_iterator<value_type>& x ) :
275
        _Deque_iterator_base<value_type>( static_cast<const _Deque_iterator_base<value_type>&>(x) )
276
      { }
277
278
    _Deque_iterator& operator =( const _Deque_iterator& ) = default;
279
280
    _Deque_iterator& operator =( const _Deque_iterator<value_type>& x )
281
      {
282
        static_cast<_Deque_iterator_base<value_type>&>(*this) = static_cast<const _Deque_iterator_base<value_type>&>(x);
283
        return *this;
284
      }
285
286
    reference operator *() const
287
      { return *this->_M_cur; }
288
289
    const pointer operator ->() const
290
      { return &*this->_M_cur; }
291
292
    difference_type operator-( const _Deque_iterator& __x ) const
293
      { return this->_M_subtract(__x); }
294
    difference_type operator-( const _Deque_iterator<_Tp>& __x ) const
295
      { return this->_M_subtract(__x); }
296
297
    _Self& operator ++()
298
      { this->_M_increment(); return *this; }
299
    _Self operator++(int)
300
      {
301
        _Self __tmp = *this;
302
        ++*this;
303
        return __tmp;
304
      }
305
306
    _Self& operator --()
307
      { this->_M_decrement(); return *this; }
308
    _Self operator--(int)
309
      {
310
        _Self __tmp = *this;
311
        --*this;
312
        return __tmp;
313
      }
314
315
    _Self& operator +=(difference_type __n)
316
      { this->_M_advance(__n); return *this; }
317
    _Self operator+(difference_type __n) const
318
      {
319
        _Self __tmp = *this;
320
        return __tmp += __n;
321
      }
322
323
    _Self& operator -=(difference_type __n)
324
      { return *this += -__n; }
325
    _Self operator -(difference_type __n) const
326
      {
327
        _Self __tmp = *this;
328
        return __tmp -= __n;
329
      }
330
331
    reference operator [](difference_type __n) const
332
      { return *(*this + __n); }
333
};
334
335
template <class _Tp>
336
inline _Deque_iterator<_Tp> _STLP_CALL operator +( ptrdiff_t __n,
337
                                                   const _Deque_iterator<_Tp>& __x )
338
{ return __x + __n; }
339
340
341
template <class _Tp>
342
inline bool _STLP_CALL operator ==( const _Deque_iterator_base<_Tp>& __x,
343
                                    const _Deque_iterator_base<_Tp>& __y )
344
{ return __x._M_cur == __y._M_cur; }
345
346
template <class _Tp>
347
inline bool _STLP_CALL operator <( const _Deque_iterator_base<_Tp>& __x,
348
                                   const _Deque_iterator_base<_Tp>& __y)
349
{
350
  return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
351
}
352
353
template <class _Tp>
354
inline bool _STLP_CALL operator !=( const _Deque_iterator_base<_Tp>& __x,
355
                                    const _Deque_iterator_base<_Tp>& __y)
356
{ return __x._M_cur != __y._M_cur; }
357
358
template <class _Tp>
359
inline bool _STLP_CALL operator >( const _Deque_iterator_base<_Tp>& __x,
360
                                   const _Deque_iterator_base<_Tp>& __y )
361
{ return __y < __x; }
362
363
template <class _Tp>
364
inline bool  _STLP_CALL operator >=( const _Deque_iterator_base<_Tp>& __x,
365
                                     const _Deque_iterator_base<_Tp>& __y )
366
{ return !(__x < __y); }
367
368
template <class _Tp>
369
inline bool  _STLP_CALL operator <=( const _Deque_iterator_base<_Tp>& __x,
370
                                     const _Deque_iterator_base<_Tp>& __y )
371
{ return !(__y < __x); }
372
373
#if defined (_STLP_USE_PTR_SPECIALIZATIONS)
374
#  define deque _STLP_PTR_IMPL_NAME(deque)
375
#elif defined (_STLP_DEBUG)
376
#  define deque _STLP_NON_DBG_NAME(deque)
377
#else
378
_STLP_MOVE_TO_STD_NAMESPACE
379
#endif
380
381
template <class _Tp, class _Alloc = allocator<_Tp> >
382
class deque
383
{
384
  private:
385
    typedef deque<_Tp, _Alloc> _Self;
386
  public:                         // Basic types
387
    typedef _Tp value_type;
388
    typedef value_type* pointer;
389
    typedef const value_type* const_pointer;
390
    typedef value_type& reference;
391
    typedef const value_type& const_reference;
392
    typedef size_t size_type;
393
    typedef ptrdiff_t difference_type;
394
    typedef random_access_iterator_tag _Iterator_category;
395
    typedef _Alloc allocator_type;
396
397
  private:
398
    typedef _STLP_PRIV _STLP_alloc_proxy<size_t, allocator_type> _Alloc_proxy;
399
400
    typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
401
    typedef _STLP_PRIV _STLP_alloc_proxy<value_type**, _Map_alloc_type> _Map_alloc_proxy;
402
403
  public:                         // Iterators
404
    typedef _STLP_PRIV _Deque_iterator<typename remove_const<_Tp>::type> iterator;
405
    typedef _STLP_PRIV _Deque_iterator<typename add_const<_Tp>::type>    const_iterator;
406
407
    _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
408
409
  protected:                      // Internal typedefs
410
    typedef pointer* _Map_pointer;
411
    iterator _M_start;
412
    iterator _M_finish;
413
    _Map_alloc_proxy  _M_map;
414
    _Alloc_proxy      _M_map_size;
415
416
    static size_t _STLP_CALL buffer_size()
417
      { return _STLP_PRIV _Deque_iterator_base<_Tp>::_S_buffer_size(); }
418
419
    void _M_initialize_map(size_t);
420
    void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
421
    void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
422
    enum { _S_initial_map_size = 8 };
423
424
  public:                         // Basic accessors
425
    iterator begin()
426
      { return this->_M_start; }
427
    iterator end()
428
      { return this->_M_finish; }
429
    const_iterator begin() const
430
      { return const_iterator(this->_M_start); }
431
    const_iterator end() const
432
      { return const_iterator(this->_M_finish); }
433
434
    reverse_iterator rbegin()
435
      { return reverse_iterator(this->_M_finish); }
436
    reverse_iterator rend()
437
      { return reverse_iterator(this->_M_start); }
438
    const_reverse_iterator rbegin() const
439
      { return const_reverse_iterator(this->_M_finish); }
440
    const_reverse_iterator rend() const
441
      { return const_reverse_iterator(this->_M_start); }
442
443
    reference operator[](size_type __n)
444
      { return this->_M_start[difference_type(__n)]; }
445
    const_reference operator[](size_type __n) const
446
      { return this->_M_start[difference_type(__n)]; }
447
448
    void _M_range_check(size_type __n) const
449
      {
450
        if (__n >= this->size()) {
451
          __stl_throw_out_of_range("deque");
452
        }
453
      }
454
    reference at(size_type __n)
455
      { _M_range_check(__n); return (*this)[__n]; }
456
    const_reference at(size_type __n) const
457
      { _M_range_check(__n); return (*this)[__n]; }
458
459
    reference front()
460
      { return *this->_M_start; }
461
    reference back()
462
      {
463
        iterator __tmp = this->_M_finish;
464
        --__tmp;
465
        return *__tmp;
466
      }
467
    const_reference front() const
468
      { return *this->_M_start; }
469
    const_reference back() const
470
      {
471
        const_iterator __tmp = this->_M_finish;
472
        --__tmp;
473
        return *__tmp;
474
      }
475
476
    size_type size() const
477
      { return this->_M_finish - this->_M_start; }
478
    size_type max_size() const
479
      { return size_type(-1); }
480
    bool empty() const
481
      { return this->_M_finish == this->_M_start; }
482
    allocator_type get_allocator() const
483
      { return this->_M_map_size; }
484
485
  public:                         // Constructor, destructor.
486
    explicit deque(const allocator_type& __a = allocator_type()) :
487
        _M_start(),
488
        _M_finish(),
489
        _M_map(__a, (value_type**)(0)),
490
        _M_map_size(__a, (size_t)0)
491
      { _M_initialize_map(0); }
492
493
    deque(const _Self& __x) :
494
        _M_start(),
495
        _M_finish(),
496
        _M_map(__x.get_allocator(), (value_type**)(0)),
497
        _M_map_size(__x.get_allocator(), (size_t)0)
498
      {
499
        _M_initialize_map(__x.size());
500
        uninitialized_copy(__x.begin(), __x.end(), this->_M_start);
501
      }
502
503
    deque(const _Self& __x, const allocator_type& __a ) :
504
        _M_start(),
505
        _M_finish(),
506
        _M_map(__a, (value_type**)(0)),
507
        _M_map_size(__a, (size_t)0)
508
      {
509
        _M_initialize_map(__x.size());
510
        uninitialized_copy(__x.begin(), __x.end(), this->_M_start);
511
      }
512
513
    explicit deque(size_type __n) :
514
        _M_start(),
515
        _M_finish(),
516
        _M_map(allocator_type(), (value_type**)(0)),
517
        _M_map_size(allocator_type(), (size_t)0)
518
      {
519
        _M_initialize_map(__n);
520
        /* _M_initialize(__n); */ _M_fill_initialize( _STLP_DEFAULT_CONSTRUCTED(_Tp) );
521
      }
522
    deque( size_type __n, const value_type& __val, const allocator_type& __a = allocator_type()) :
523
        _M_start(),
524
        _M_finish(),
525
        _M_map(__a, (value_type**)(0)),
526
        _M_map_size(__a, (size_t)0)
527
      {
528
        _M_initialize_map(__n);
529
        _M_fill_initialize( __val );
530
      }
531
532
  protected:
533
    template <class _Integer>
534
    void _M_initialize_dispatch( _Integer __n, _Integer __x, const true_type& )
535
      {
536
        this->_M_initialize_map(__n);
537
        _M_fill_initialize( __x );
538
      }
539
540
    template <class _InputIter>
541
    void _M_initialize_dispatch( _InputIter __first, _InputIter __last, const false_type& )
542
      { _M_range_initialize(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); }
543
544
  public:
545
    // Check whether it's an integral type.  If so, it's not an iterator.
546
    template <class _InputIterator>
547
    deque( _InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type() ) :
548
        _M_start(),
549
        _M_finish(),
550
        _M_map(__a, (value_type**)(0)),
551
        _M_map_size(__a, (size_t)0)
552
      { _M_initialize_dispatch(__first, __last, typename is_integral<_InputIterator>::type() ); }
553
554
    deque( deque&& __x ) :
555
        _M_start(__x._M_start),
556
        _M_finish(__x._M_finish),
557
        _M_map(__x.get_allocator(), (value_type**)(0)),
558
        _M_map_size(__x.get_allocator(), (size_t)0)
559
      {
560
        _STLP_STD::swap( _M_map._M_data, __x._M_map._M_data);
561
        _STLP_STD::swap( _M_map_size._M_data, __x._M_map_size._M_data);
562
        __x._M_finish = __x._M_start;
563
      }
564
565
    deque( deque&& __x, const allocator_type& __a ) :
566
        _M_start(),
567
        _M_finish(),
568
        _M_map(__a, (value_type**)(0)),
569
        _M_map_size(__a, (size_t)0)
570
      {
571
        if ( __x.get_allocator() == __a ) {
572
          _M_start = __x._M_start;
573
          _M_finish = __x._M_finish;
574
          _STLP_STD::swap( _M_map._M_data, __x._M_map._M_data);
575
          _STLP_STD::swap( _M_map_size._M_data, __x._M_map_size._M_data);
576
          __x._M_finish = __x._M_start;          
577
        } else {
578
          _M_initialize_map(__x._M_finish - __x._M_start);
579
          uninitialized_copy(__x._M_start, __x._M_finish, this->_M_start);
580
          if (__x._M_map._M_data) {
581
            __x._M_destroy_nodes(_M_start._M_node, this->_M_finish._M_node + 1);
582
            __x._M_map.deallocate(__x._M_map._M_data, __x._M_map_size._M_data);
583
            __x._M_finish = __x._M_start;
584
            __x._M_map._M_data = 0;
585
            __x._M_map_size._M_data = 0;
586
          }
587
        }
588
      }
589
590
    ~deque()
591
      {
592
        _STLP_STD::detail::_Destroy_Range(this->_M_start, this->_M_finish);
593
        if (_M_map._M_data) {
594
          _M_destroy_nodes(_M_start._M_node, this->_M_finish._M_node + 1);
595
          _M_map.deallocate(_M_map._M_data, _M_map_size._M_data);
596
        }
597
      }
598
599
    _Self& operator =(const _Self& __x);
600
    _Self& operator =(_Self&& __x);
601
602
    void swap(_Self& __x)
603
      {
604
        _STLP_STD::swap(this->_M_start, __x._M_start);
605
        _STLP_STD::swap(this->_M_finish, __x._M_finish);
606
        // this->_M_map.swap(__x._M_map);
607
        _STLP_STD::swap( this->_M_map, __x._M_map );
608
        // this->_M_map_size.swap(__x._M_map_size);
609
        _STLP_STD::swap( this->_M_map_size, __x._M_map_size );
610
      }
611
#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
612
    void _M_swap_workaround(_Self& __x)
613
      { swap(__x); }
614
#endif
615
616
  public:
617
    // assign(), a generalized assignment member function.  Two
618
    // versions: one that takes a count, and one that takes a range.
619
    // The range version is a member template, so we dispatch on whether
620
    // or not the type is an integer.
621
622
    void _M_fill_assign(size_type __n, const _Tp& __val)
623
      {
624
        if (__n > size()) {
625
          _STLP_STD::fill(begin(), end(), __val);
626
          insert(end(), __n - size(), __val);
627
        } else {
628
          erase(begin() + __n, end());
629
          _STLP_STD::fill(begin(), end(), __val);
630
        }
631
      }
632
633
    void assign(size_type __n, const _Tp& __val)
634
      { _M_fill_assign(__n, __val); }
635
636
    template <class _InputIterator>
637
    void assign(_InputIterator __first, _InputIterator __last)
638
      {
639
         typedef typename is_integral<_InputIterator>::type _Integral;
640
         _M_assign_dispatch(__first, __last, _Integral());
641
      }
642
643
  private:                        // helper functions for assign()
644
645
    template <class _Integer>
646
    void _M_assign_dispatch( _Integer __n, _Integer __val, const true_type& /*_IsIntegral*/)
647
      { _M_fill_assign((size_type) __n, (_Tp) __val); }
648
649
    template <class _InputIterator>
650
    void _M_assign_dispatch( _InputIterator __first, _InputIterator __last,
651
                             const false_type& /*_IsIntegral*/)
652
      { _M_assign_aux(__first, __last, typename iterator_traits<_InputIterator>::iterator_category()); }
653
654
    template <class _InputIter>
655
    void _M_assign_aux( _InputIter __first, _InputIter __last, const input_iterator_tag& )
656
      {
657
         iterator __cur = begin();
658
         for ( ; __first != __last && __cur != end(); ++__cur, ++__first) {
659
           *__cur = *__first;
660
         }
661
         if (__first == __last) {
662
           erase(__cur, end());
663
         } else {
664
           insert(end(), __first, __last);
665
         }
666
      }
667
    
668
    template <class _ForwardIterator>
669
    void _M_assign_aux( _ForwardIterator __first, _ForwardIterator __last, const forward_iterator_tag& )
670
      {
671
        size_type __len = _STLP_STD::distance(__first, __last);
672
        if (__len > size()) {
673
          _ForwardIterator __mid = __first;
674
          _STLP_STD::advance(__mid, size());
675
          _STLP_STD::copy(__first, __mid, begin());
676
          insert(end(), __mid, __last);
677
        } else {
678
          erase(_STLP_STD::copy(__first, __last, begin()), end());
679
        }
680
      }
681
682
683
  public:                         // push_* and pop_*
684
685
    void push_back( const value_type& __t )
686
      {
687
        if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) {
688
          _Self::get_allocator().construct( this->_M_finish._M_cur, __t );
689
          ++this->_M_finish._M_cur;
690
        } else {
691
          _M_push_back_aux_v(__t);
692
        }
693
      }
694
695
    void push_front( const value_type& __t )
696
      {
697
        if (this->_M_start._M_cur != this->_M_start._M_first) {
698
          _Self::get_allocator().construct( this->_M_start._M_cur - 1, __t );
699
          --this->_M_start._M_cur;
700
        } else {
701
          _M_push_front_aux_v(__t);
702
        }
703
      }
704
705
    void pop_back()
706
      {
707
        if (this->_M_finish._M_cur != this->_M_finish._M_first) {
708
          --this->_M_finish._M_cur;
709
          _Self::get_allocator().destroy( this->_M_finish._M_cur );
710
        } else {
711
          _M_pop_back_aux();
712
          _Self::get_allocator().destroy( this->_M_finish._M_cur );
713
        }
714
      }
715
716
    void pop_front()
717
      {
718
        _Self::get_allocator().destroy( this->_M_start._M_cur );
719
        _M_pop_front_aux();
720
      }
721
722
  public:                         // Insert
723
    iterator insert( iterator __pos, const value_type& __x )
724
      {
725
        if (__pos._M_cur == this->_M_start._M_cur) {
726
          push_front(__x);
727
          return this->_M_start;
728
        } else if (__pos._M_cur == this->_M_finish._M_cur) {
729
          push_back(__x);
730
          iterator __tmp = this->_M_finish;
731
          --__tmp;
732
          return __tmp;
733
        } else {
734
          return _M_fill_insert_aux(__pos, 1, __x, /* _Movable() */ true_type() );
735
        }
736
      }
737
738
    void insert(iterator __pos, size_type __n, const value_type& __x)
739
      { _M_fill_insert(__pos, __n, __x); }
740
741
  protected:
742
    iterator _M_fill_insert_aux(iterator __pos, size_type __n, const value_type& __x, const true_type& /*_Movable*/);
743
    iterator _M_fill_insert_aux(iterator __pos, size_type __n, const value_type& __x, const false_type& /*_Movable*/);
744
745
    void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
746
747
    template <class _Integer>
748
    void _M_insert_dispatch( iterator __pos, _Integer __n, _Integer __x,
749
                             const true_type& /*_IsIntegral*/)
750
      { _M_fill_insert(__pos, (size_type) __n, (value_type) __x); }
751
752
    template <class _InputIterator>
753
    void _M_insert_dispatch( iterator __pos, _InputIterator __first, _InputIterator __last,
754
                             const false_type& /*_IsIntegral*/)
755
      { _M_insert(__pos, __first, __last, typename iterator_traits<_InputIterator>::iterator_category()); }
756
757
  public:
758
    // Check whether it's an integral type.  If so, it's not an iterator.
759
    template <class _InputIterator>
760
    void insert( iterator __pos, _InputIterator __first, _InputIterator __last )
761
      {
762
        typedef typename is_integral<_InputIterator>::type _Integral;
763
        _M_insert_dispatch(__pos, __first, __last, _Integral());
764
      }
765
766
  public:
767
    void resize(size_type __new_size, const value_type& __x)
768
      {
769
        const size_type __len = size();
770
        if (__new_size < __len) {
771
          erase(this->_M_start + __new_size, this->_M_finish);
772
        } else {
773
          insert(this->_M_finish, __new_size - __len, __x);
774
        }
775
      }
776
777
  protected:
778
    iterator _M_erase(iterator __pos, const true_type& /*_Movable*/);
779
    iterator _M_erase(iterator __pos, const false_type& /*_Movable*/);
780
781
    iterator _M_erase(iterator __first, iterator __last, const true_type& /*_Movable*/);
782
    iterator _M_erase(iterator __first, iterator __last, const false_type& /*_Movable*/);
783
  public:                         // Erase
784
    iterator erase(iterator __pos)
785
      {
786
        return _M_erase(__pos, /* _Movable() */ typename is_trivially_move_constructible<value_type>::type() );
787
      }
788
    iterator erase(iterator __first, iterator __last)
789
      {
790
        if (__first == this->_M_start && __last == this->_M_finish) {
791
          clear();
792
          return this->_M_finish;
793
        } else {
794
          if (__first == __last) {
795
            return __first;
796
          }
797
          return _M_erase(__first, __last, /* _Movable() */ false_type() );
798
        }
799
      }
800
801
    void clear();
802
803
  protected:                        // Internal construction/destruction
804
    void _M_fill_initialize( const value_type& __val );
805
806
    template <class _InputIterator>
807
    void _M_range_initialize( _InputIterator __first, _InputIterator __last,
808
                              const input_iterator_tag& )
809
      {
810
        this->_M_initialize_map(0);
811
        _STLP_TRY {
812
          for ( ; __first != __last; ++__first) {
813
            push_back(*__first);
814
          }
815
        }
816
        _STLP_UNWIND(clear())
817
      }
818
819
    template <class _ForwardIterator>
820
    void  _M_range_initialize( _ForwardIterator __first, _ForwardIterator __last,
821
                               const forward_iterator_tag& )
822
      {
823
        size_type __n = _STLP_STD::distance(__first, __last);
824
        this->_M_initialize_map(__n);
825
        _Map_pointer __cur_node = this->_M_start._M_node;
826
        _STLP_TRY {
827
          for (; __cur_node < this->_M_finish._M_node; ++__cur_node) {
828
            _ForwardIterator __mid = __first;
829
            _STLP_STD::advance(__mid, this->buffer_size());
830
            _STLP_STD::uninitialized_copy(__first, __mid, *__cur_node);
831
            __first = __mid;
832
          }
833
          _STLP_STD::uninitialized_copy(__first, __last, this->_M_finish._M_first);
834
        }
835
        _STLP_UNWIND(_STLP_STD::detail::_Destroy_Range(this->_M_start, iterator(*__cur_node, __cur_node)))
836
      }
837
838
  protected:                        // Internal push_* and pop_*
839
840
    void _M_push_back_aux_v(const value_type&);
841
    void _M_push_front_aux_v(const value_type&);
842
    void _M_pop_back_aux();
843
    void _M_pop_front_aux();
844
845
  protected:                        // Internal insert functions
846
847
    template <class _InputIterator>
848
    void _M_insert( iterator __pos, _InputIterator __first, _InputIterator __last,
849
                    const input_iterator_tag& )
850
      { _STLP_STD::copy(__first, __last, inserter(*this, __pos)); }
851
852
    template <class _ForwardIterator>
853
    void  _M_insert( iterator __pos,
854
                     _ForwardIterator __first, _ForwardIterator __last,
855
                     const forward_iterator_tag& )
856
      {
857
        size_type __n = _STLP_STD::distance(__first, __last);
858
        if (__pos._M_cur == this->_M_start._M_cur) {
859
          iterator __new_start = _M_reserve_elements_at_front(__n);
860
          _STLP_TRY {
861
            uninitialized_copy(__first, __last, __new_start);
862
            this->_M_start = __new_start;
863
          }
864
          _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
865
        } else if (__pos._M_cur == this->_M_finish._M_cur) {
866
          iterator __new_finish = _M_reserve_elements_at_back(__n);
867
          _STLP_TRY {
868
            uninitialized_copy(__first, __last, this->_M_finish);
869
            this->_M_finish = __new_finish;
870
          }
871
          _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
872
        } else {
873
          _M_insert_range_aux(__pos, __first, __last, __n, /* _Movable() */ true_type() );
874
        }
875
      }
876
877
    template <class _ForwardIterator>
878
    void _M_insert_range_aux( iterator __pos,
879
                              _ForwardIterator __first, _ForwardIterator __last,
880
                              size_type __n, const false_type& /*_Movable*/)
881
      {
882
        const difference_type __elemsbefore = __pos - this->_M_start;
883
        size_type __length = size();
884
        if (__elemsbefore <= difference_type(__length / 2)) {
885
          iterator __new_start = _M_reserve_elements_at_front(__n);
886
          __pos = this->_M_start + __elemsbefore;
887
          _STLP_TRY {
888
            iterator __dst = __new_start;
889
            iterator __src = this->_M_start;
890
            for (; __src != __pos; ++__dst, ++__src) {
891
              _Self::get_allocator().construct( &(*__dst), _STLP_STD::move(*__src) );
892
              _Self::get_allocator().destroy( &(*__src) );
893
            }
894
            this->_M_start = __new_start;
895
            uninitialized_copy(__first, __last, __dst);
896
          }
897
          _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
898
        } else {
899
          iterator __new_finish = _M_reserve_elements_at_back(__n);
900
          const difference_type __elemsafter = difference_type(__length) - __elemsbefore;
901
          __pos = this->_M_finish - __elemsafter;
902
          _STLP_TRY {
903
            iterator __dst = __new_finish;
904
            iterator __src = this->_M_finish;
905
            for (--__src, --__dst; __src >= __pos; --__src, --__dst) {
906
              _Self::get_allocator().construct( &(*__dst), _STLP_STD::move(*__src) );
907
              _Self::get_allocator().destroy( &(*__src) );
908
            }
909
            this->_M_finish = __new_finish;
910
            uninitialized_copy(__first, __last, __pos);
911
          }
912
          _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
913
        }
914
      }
915
916
    template <class _ForwardIterator>
917
    void _M_insert_range_aux( iterator __pos,
918
                              _ForwardIterator __first, _ForwardIterator __last,
919
                              size_type __n, const true_type& /*_Movable*/)
920
      {
921
        const difference_type __elemsbefore = __pos - this->_M_start;
922
        size_type __length = size();
923
        if (__elemsbefore <= difference_type(__length / 2)) {
924
          iterator __new_start = _M_reserve_elements_at_front(__n);
925
          iterator __old_start = this->_M_start;
926
          __pos = this->_M_start + __elemsbefore;
927
          _STLP_TRY {
928
            if (__elemsbefore >= difference_type(__n)) {
929
              iterator __start_n = this->_M_start + difference_type(__n);
930
              _STLP_STD::uninitialized_copy(this->_M_start, __start_n, __new_start);
931
              this->_M_start = __new_start;
932
              _STLP_STD::copy(__start_n, __pos, __old_start);
933
              _STLP_STD::copy(__first, __last, __pos - difference_type(__n));
934
            } else {
935
              _ForwardIterator __mid = __first;
936
              _STLP_STD::advance(__mid, difference_type(__n) - __elemsbefore);
937
              _STLP_PRIV __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid, __new_start);
938
              this->_M_start = __new_start;
939
              _STLP_STD::copy(__mid, __last, __old_start);
940
            }
941
          }
942
          _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
943
        } else {
944
          iterator __new_finish = _M_reserve_elements_at_back(__n);
945
          iterator __old_finish = this->_M_finish;
946
          const difference_type __elemsafter = difference_type(__length) - __elemsbefore;
947
          __pos = this->_M_finish - __elemsafter;
948
          _STLP_TRY {
949
            if (__elemsafter > difference_type(__n)) {
950
              iterator __finish_n = this->_M_finish - difference_type(__n);
951
              _STLP_STD::uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish);
952
              this->_M_finish = __new_finish;
953
              _STLP_STD::copy_backward(__pos, __finish_n, __old_finish);
954
              _STLP_STD::copy(__first, __last, __pos);
955
            } else {
956
              _ForwardIterator __mid = __first;
957
              _STLP_STD::advance(__mid, __elemsafter);
958
              _STLP_PRIV __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish);
959
              this->_M_finish = __new_finish;
960
              _STLP_STD::copy(__first, __mid, __pos);
961
            }
962
          }
963
          _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
964
        }
965
      }
966
967
    iterator _M_reserve_elements_at_front(size_type __n)
968
      {
969
        size_type __vacancies = this->_M_start._M_cur - this->_M_start._M_first;
970
        if (__n > __vacancies) {
971
          _M_new_elements_at_front(__n - __vacancies);
972
        }
973
        return this->_M_start - difference_type(__n);
974
      }
975
976
    iterator _M_reserve_elements_at_back(size_type __n)
977
      {
978
        size_type __vacancies = (this->_M_finish._M_last - this->_M_finish._M_cur) - 1;
979
        if (__n > __vacancies) {
980
          _M_new_elements_at_back(__n - __vacancies);
981
        }
982
        return this->_M_finish + difference_type(__n);
983
      }
984
985
    void _M_new_elements_at_front(size_type __new_elements);
986
    void _M_new_elements_at_back(size_type __new_elements);
987
988
  protected:                      // Allocation of _M_map and nodes
989
990
    // Makes sure the _M_map has space for new nodes.  Does not actually
991
    //  add the nodes.  Can invalidate _M_map pointers.  (And consequently,
992
    //  deque iterators.)
993
994
    void _M_reserve_map_at_back (size_type __nodes_to_add = 1)
995
    {
996
      if (__nodes_to_add + 1 > this->_M_map_size._M_data - (this->_M_finish._M_node - this->_M_map._M_data)) {
997
        _M_reallocate_map(__nodes_to_add, false);
998
      }
999
    }
1000
1001
    void _M_reserve_map_at_front (size_type __nodes_to_add = 1)
1002
    {
1003
      if (__nodes_to_add > size_type(this->_M_start._M_node - this->_M_map._M_data)) {
1004
        _M_reallocate_map(__nodes_to_add, true);
1005
      }
1006
    }
1007
1008
    void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
1009
};
1010
1011
#if defined (deque)
1012
_STLP_MOVE_TO_STD_NAMESPACE
1013
#  undef deque
1014
#endif // deque
1015
1016
_STLP_END_NAMESPACE
1017
1018
#include <stl/_deque.c>
1019
1020
#if defined (_STLP_USE_PTR_SPECIALIZATIONS)
1021
#  include <stl/pointers/_deque.h>
1022
#endif
1023
1024
#if defined (_STLP_DEBUG)
1025
#  include <stl/debug/_deque.h>
1026
#endif
1027
1028
_STLP_BEGIN_NAMESPACE
1029
1030
#define _STLP_TEMPLATE_CONTAINER deque<_Tp, _Alloc>
1031
#define _STLP_TEMPLATE_HEADER    template <class _Tp, class _Alloc>
1032
#include <stl/_relops_cont.h>
1033
#undef _STLP_TEMPLATE_CONTAINER
1034
#undef _STLP_TEMPLATE_HEADER
1035
1036
_STLP_END_NAMESPACE
1037
1038
#if (_STLP_OUTERMOST_HEADER_ID == 0x22)
1039
#  include <stl/_epilog.h>
1040
#  undef _STLP_OUTERMOST_HEADER_ID
1041
#endif
1042
1043
#endif /* _STLP_DEQUE */
1044
1045
// Local Variables:
1046
// mode:C++
1047
// End: