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
// Deque implementation (out of line) -*- C++ -*-
2
 
3
// Copyright (C) 2001-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
/*
26
 *
27
 * Copyright (c) 1994
28
 * Hewlett-Packard Company
29
 *
30
 * Permission to use, copy, modify, distribute and sell this software
31
 * and its documentation for any purpose is hereby granted without fee,
32
 * provided that the above copyright notice appear in all copies and
33
 * that both that copyright notice and this permission notice appear
34
 * in supporting documentation.  Hewlett-Packard Company makes no
35
 * representations about the suitability of this software for any
36
 * purpose.  It is provided "as is" without express or implied warranty.
37
 *
38
 *
39
 * Copyright (c) 1997
40
 * Silicon Graphics Computer Systems, Inc.
41
 *
42
 * Permission to use, copy, modify, distribute and sell this software
43
 * and its documentation for any purpose is hereby granted without fee,
44
 * provided that the above copyright notice appear in all copies and
45
 * that both that copyright notice and this permission notice appear
46
 * in supporting documentation.  Silicon Graphics makes no
47
 * representations about the suitability of this software for any
48
 * purpose.  It is provided "as is" without express or implied warranty.
49
 */
50
 
51
/** @file bits/deque.tcc
52
 *  This is an internal header file, included by other library headers.
53
 *  Do not attempt to use it directly. @headername{deque}
54
 */
55
 
56
#ifndef _DEQUE_TCC
57
#define _DEQUE_TCC 1
58
 
59
namespace std _GLIBCXX_VISIBILITY(default)
60
{
61
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
62
 
63
#if __cplusplus >= 201103L
64
  template 
65
    void
66
    deque<_Tp, _Alloc>::
67
    _M_default_initialize()
68
    {
69
      _Map_pointer __cur;
70
      __try
71
        {
72
          for (__cur = this->_M_impl._M_start._M_node;
73
	       __cur < this->_M_impl._M_finish._M_node;
74
	       ++__cur)
75
            std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
76
					   _M_get_Tp_allocator());
77
          std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
78
					 this->_M_impl._M_finish._M_cur,
79
					 _M_get_Tp_allocator());
80
        }
81
      __catch(...)
82
        {
83
          std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
84
			_M_get_Tp_allocator());
85
          __throw_exception_again;
86
        }
87
    }
88
#endif
89
 
90
  template 
91
    deque<_Tp, _Alloc>&
92
    deque<_Tp, _Alloc>::
93
    operator=(const deque& __x)
94
    {
95
      const size_type __len = size();
96
      if (&__x != this)
97
	{
98
	  if (__len >= __x.size())
99
	    _M_erase_at_end(std::copy(__x.begin(), __x.end(),
100
				      this->_M_impl._M_start));
101
	  else
102
	    {
103
	      const_iterator __mid = __x.begin() + difference_type(__len);
104
	      std::copy(__x.begin(), __mid, this->_M_impl._M_start);
105
	      insert(this->_M_impl._M_finish, __mid, __x.end());
106
	    }
107
	}
108
      return *this;
109
    }
110
 
111
#if __cplusplus >= 201103L
112
  template
113
    template
114
      void
115
      deque<_Tp, _Alloc>::
116
      emplace_front(_Args&&... __args)
117
      {
118
	if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
119
	  {
120
	    this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1,
121
				    std::forward<_Args>(__args)...);
122
	    --this->_M_impl._M_start._M_cur;
123
	  }
124
	else
125
	  _M_push_front_aux(std::forward<_Args>(__args)...);
126
      }
127
 
128
  template
129
    template
130
      void
131
      deque<_Tp, _Alloc>::
132
      emplace_back(_Args&&... __args)
133
      {
134
	if (this->_M_impl._M_finish._M_cur
135
	    != this->_M_impl._M_finish._M_last - 1)
136
	  {
137
	    this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
138
				    std::forward<_Args>(__args)...);
139
	    ++this->_M_impl._M_finish._M_cur;
140
	  }
141
	else
142
	  _M_push_back_aux(std::forward<_Args>(__args)...);
143
      }
144
#endif
145
 
146
  template 
147
    typename deque<_Tp, _Alloc>::iterator
148
    deque<_Tp, _Alloc>::
149
    insert(iterator __position, const value_type& __x)
150
    {
151
      if (__position._M_cur == this->_M_impl._M_start._M_cur)
152
	{
153
	  push_front(__x);
154
	  return this->_M_impl._M_start;
155
	}
156
      else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
157
	{
158
	  push_back(__x);
159
	  iterator __tmp = this->_M_impl._M_finish;
160
	  --__tmp;
161
	  return __tmp;
162
	}
163
      else
164
        return _M_insert_aux(__position, __x);
165
    }
166
 
167
#if __cplusplus >= 201103L
168
  template
169
    template
170
      typename deque<_Tp, _Alloc>::iterator
171
      deque<_Tp, _Alloc>::
172
      emplace(iterator __position, _Args&&... __args)
173
      {
174
	if (__position._M_cur == this->_M_impl._M_start._M_cur)
175
	  {
176
	    emplace_front(std::forward<_Args>(__args)...);
177
	    return this->_M_impl._M_start;
178
	  }
179
	else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
180
	  {
181
	    emplace_back(std::forward<_Args>(__args)...);
182
	    iterator __tmp = this->_M_impl._M_finish;
183
	    --__tmp;
184
	    return __tmp;
185
	  }
186
	else
187
	  return _M_insert_aux(__position, std::forward<_Args>(__args)...);
188
      }
189
#endif
190
 
191
  template 
192
    typename deque<_Tp, _Alloc>::iterator
193
    deque<_Tp, _Alloc>::
194
    erase(iterator __position)
195
    {
196
      iterator __next = __position;
197
      ++__next;
198
      const difference_type __index = __position - begin();
199
      if (static_cast(__index) < (size() >> 1))
200
	{
201
	  if (__position != begin())
202
	    _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
203
	  pop_front();
204
	}
205
      else
206
	{
207
	  if (__next != end())
208
	    _GLIBCXX_MOVE3(__next, end(), __position);
209
	  pop_back();
210
	}
211
      return begin() + __index;
212
    }
213
 
214
  template 
215
    typename deque<_Tp, _Alloc>::iterator
216
    deque<_Tp, _Alloc>::
217
    erase(iterator __first, iterator __last)
218
    {
219
      if (__first == __last)
220
	return __first;
221
      else if (__first == begin() && __last == end())
222
	{
223
	  clear();
224
	  return end();
225
	}
226
      else
227
	{
228
	  const difference_type __n = __last - __first;
229
	  const difference_type __elems_before = __first - begin();
230
	  if (static_cast(__elems_before) <= (size() - __n) / 2)
231
	    {
232
	      if (__first != begin())
233
		_GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
234
	      _M_erase_at_begin(begin() + __n);
235
	    }
236
	  else
237
	    {
238
	      if (__last != end())
239
		_GLIBCXX_MOVE3(__last, end(), __first);
240
	      _M_erase_at_end(end() - __n);
241
	    }
242
	  return begin() + __elems_before;
243
	}
244
    }
245
 
246
  template 
247
    template 
248
      void
249
      deque<_Tp, _Alloc>::
250
      _M_assign_aux(_InputIterator __first, _InputIterator __last,
251
		    std::input_iterator_tag)
252
      {
253
        iterator __cur = begin();
254
        for (; __first != __last && __cur != end(); ++__cur, ++__first)
255
          *__cur = *__first;
256
        if (__first == __last)
257
          _M_erase_at_end(__cur);
258
        else
259
          insert(end(), __first, __last);
260
      }
261
 
262
  template 
263
    void
264
    deque<_Tp, _Alloc>::
265
    _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
266
    {
267
      if (__pos._M_cur == this->_M_impl._M_start._M_cur)
268
	{
269
	  iterator __new_start = _M_reserve_elements_at_front(__n);
270
	  __try
271
	    {
272
	      std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
273
					  __x, _M_get_Tp_allocator());
274
	      this->_M_impl._M_start = __new_start;
275
	    }
276
	  __catch(...)
277
	    {
278
	      _M_destroy_nodes(__new_start._M_node,
279
			       this->_M_impl._M_start._M_node);
280
	      __throw_exception_again;
281
	    }
282
	}
283
      else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
284
	{
285
	  iterator __new_finish = _M_reserve_elements_at_back(__n);
286
	  __try
287
	    {
288
	      std::__uninitialized_fill_a(this->_M_impl._M_finish,
289
					  __new_finish, __x,
290
					  _M_get_Tp_allocator());
291
	      this->_M_impl._M_finish = __new_finish;
292
	    }
293
	  __catch(...)
294
	    {
295
	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
296
			       __new_finish._M_node + 1);
297
	      __throw_exception_again;
298
	    }
299
	}
300
      else
301
        _M_insert_aux(__pos, __n, __x);
302
    }
303
 
304
#if __cplusplus >= 201103L
305
  template 
306
    void
307
    deque<_Tp, _Alloc>::
308
    _M_default_append(size_type __n)
309
    {
310
      if (__n)
311
	{
312
	  iterator __new_finish = _M_reserve_elements_at_back(__n);
313
	  __try
314
	    {
315
	      std::__uninitialized_default_a(this->_M_impl._M_finish,
316
					     __new_finish,
317
					     _M_get_Tp_allocator());
318
	      this->_M_impl._M_finish = __new_finish;
319
	    }
320
	  __catch(...)
321
	    {
322
	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
323
			       __new_finish._M_node + 1);
324
	      __throw_exception_again;
325
	    }
326
	}
327
    }
328
 
329
  template 
330
    bool
331
    deque<_Tp, _Alloc>::
332
    _M_shrink_to_fit()
333
    {
334
      const difference_type __front_capacity
335
	= (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
336
      if (__front_capacity == 0)
337
	return false;
338
 
339
      const difference_type __back_capacity
340
	= (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
341
      if (__front_capacity + __back_capacity < _S_buffer_size())
342
	return false;
343
 
344
      return std::__shrink_to_fit_aux::_S_do_it(*this);
345
    }
346
#endif
347
 
348
  template 
349
    void
350
    deque<_Tp, _Alloc>::
351
    _M_fill_initialize(const value_type& __value)
352
    {
353
      _Map_pointer __cur;
354
      __try
355
        {
356
          for (__cur = this->_M_impl._M_start._M_node;
357
	       __cur < this->_M_impl._M_finish._M_node;
358
	       ++__cur)
359
            std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
360
					__value, _M_get_Tp_allocator());
361
          std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
362
				      this->_M_impl._M_finish._M_cur,
363
				      __value, _M_get_Tp_allocator());
364
        }
365
      __catch(...)
366
        {
367
          std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
368
			_M_get_Tp_allocator());
369
          __throw_exception_again;
370
        }
371
    }
372
 
373
  template 
374
    template 
375
      void
376
      deque<_Tp, _Alloc>::
377
      _M_range_initialize(_InputIterator __first, _InputIterator __last,
378
                          std::input_iterator_tag)
379
      {
380
        this->_M_initialize_map(0);
381
        __try
382
          {
383
            for (; __first != __last; ++__first)
384
#if __cplusplus >= 201103L
385
	      emplace_back(*__first);
386
#else
387
              push_back(*__first);
388
#endif
389
          }
390
        __catch(...)
391
          {
392
            clear();
393
            __throw_exception_again;
394
          }
395
      }
396
 
397
  template 
398
    template 
399
      void
400
      deque<_Tp, _Alloc>::
401
      _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
402
                          std::forward_iterator_tag)
403
      {
404
        const size_type __n = std::distance(__first, __last);
405
        this->_M_initialize_map(__n);
406
 
407
        _Map_pointer __cur_node;
408
        __try
409
          {
410
            for (__cur_node = this->_M_impl._M_start._M_node;
411
                 __cur_node < this->_M_impl._M_finish._M_node;
412
                 ++__cur_node)
413
	      {
414
		_ForwardIterator __mid = __first;
415
		std::advance(__mid, _S_buffer_size());
416
		std::__uninitialized_copy_a(__first, __mid, *__cur_node,
417
					    _M_get_Tp_allocator());
418
		__first = __mid;
419
	      }
420
            std::__uninitialized_copy_a(__first, __last,
421
					this->_M_impl._M_finish._M_first,
422
					_M_get_Tp_allocator());
423
          }
424
        __catch(...)
425
          {
426
            std::_Destroy(this->_M_impl._M_start,
427
			  iterator(*__cur_node, __cur_node),
428
			  _M_get_Tp_allocator());
429
            __throw_exception_again;
430
          }
431
      }
432
 
433
  // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
434
  template
435
#if __cplusplus >= 201103L
436
    template
437
      void
438
      deque<_Tp, _Alloc>::
439
      _M_push_back_aux(_Args&&... __args)
440
#else
441
      void
442
      deque<_Tp, _Alloc>::
443
      _M_push_back_aux(const value_type& __t)
444
#endif
445
      {
446
	_M_reserve_map_at_back();
447
	*(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
448
	__try
449
	  {
450
#if __cplusplus >= 201103L
451
	    this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
452
				    std::forward<_Args>(__args)...);
453
#else
454
	    this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
455
#endif
456
	    this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
457
						+ 1);
458
	    this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
459
	  }
460
	__catch(...)
461
	  {
462
	    _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
463
	    __throw_exception_again;
464
	  }
465
      }
466
 
467
  // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
468
  template
469
#if __cplusplus >= 201103L
470
    template
471
      void
472
      deque<_Tp, _Alloc>::
473
      _M_push_front_aux(_Args&&... __args)
474
#else
475
      void
476
      deque<_Tp, _Alloc>::
477
      _M_push_front_aux(const value_type& __t)
478
#endif
479
      {
480
	_M_reserve_map_at_front();
481
	*(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
482
	__try
483
	  {
484
	    this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
485
					       - 1);
486
	    this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
487
#if __cplusplus >= 201103L
488
	    this->_M_impl.construct(this->_M_impl._M_start._M_cur,
489
				    std::forward<_Args>(__args)...);
490
#else
491
	    this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
492
#endif
493
	  }
494
	__catch(...)
495
	  {
496
	    ++this->_M_impl._M_start;
497
	    _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
498
	    __throw_exception_again;
499
	  }
500
      }
501
 
502
  // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
503
  template 
504
    void deque<_Tp, _Alloc>::
505
    _M_pop_back_aux()
506
    {
507
      _M_deallocate_node(this->_M_impl._M_finish._M_first);
508
      this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
509
      this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
510
      this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
511
    }
512
 
513
  // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
514
  // Note that if the deque has at least one element (a precondition for this
515
  // member function), and if
516
  //   _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
517
  // then the deque must have at least two nodes.
518
  template 
519
    void deque<_Tp, _Alloc>::
520
    _M_pop_front_aux()
521
    {
522
      this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
523
      _M_deallocate_node(this->_M_impl._M_start._M_first);
524
      this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
525
      this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
526
    }
527
 
528
  template 
529
    template 
530
      void
531
      deque<_Tp, _Alloc>::
532
      _M_range_insert_aux(iterator __pos,
533
                          _InputIterator __first, _InputIterator __last,
534
                          std::input_iterator_tag)
535
      { std::copy(__first, __last, std::inserter(*this, __pos)); }
536
 
537
  template 
538
    template 
539
      void
540
      deque<_Tp, _Alloc>::
541
      _M_range_insert_aux(iterator __pos,
542
                          _ForwardIterator __first, _ForwardIterator __last,
543
                          std::forward_iterator_tag)
544
      {
545
        const size_type __n = std::distance(__first, __last);
546
        if (__pos._M_cur == this->_M_impl._M_start._M_cur)
547
	  {
548
	    iterator __new_start = _M_reserve_elements_at_front(__n);
549
	    __try
550
	      {
551
		std::__uninitialized_copy_a(__first, __last, __new_start,
552
					    _M_get_Tp_allocator());
553
		this->_M_impl._M_start = __new_start;
554
	      }
555
	    __catch(...)
556
	      {
557
		_M_destroy_nodes(__new_start._M_node,
558
				 this->_M_impl._M_start._M_node);
559
		__throw_exception_again;
560
	      }
561
	  }
562
        else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
563
	  {
564
	    iterator __new_finish = _M_reserve_elements_at_back(__n);
565
	    __try
566
	      {
567
		std::__uninitialized_copy_a(__first, __last,
568
					    this->_M_impl._M_finish,
569
					    _M_get_Tp_allocator());
570
		this->_M_impl._M_finish = __new_finish;
571
	      }
572
	    __catch(...)
573
	      {
574
		_M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
575
				 __new_finish._M_node + 1);
576
		__throw_exception_again;
577
	      }
578
	  }
579
        else
580
          _M_insert_aux(__pos, __first, __last, __n);
581
      }
582
 
583
  template
584
#if __cplusplus >= 201103L
585
    template
586
      typename deque<_Tp, _Alloc>::iterator
587
      deque<_Tp, _Alloc>::
588
      _M_insert_aux(iterator __pos, _Args&&... __args)
589
      {
590
	value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
591
#else
592
    typename deque<_Tp, _Alloc>::iterator
593
      deque<_Tp, _Alloc>::
594
      _M_insert_aux(iterator __pos, const value_type& __x)
595
      {
596
	value_type __x_copy = __x; // XXX copy
597
#endif
598
	difference_type __index = __pos - this->_M_impl._M_start;
599
	if (static_cast(__index) < size() / 2)
600
	  {
601
	    push_front(_GLIBCXX_MOVE(front()));
602
	    iterator __front1 = this->_M_impl._M_start;
603
	    ++__front1;
604
	    iterator __front2 = __front1;
605
	    ++__front2;
606
	    __pos = this->_M_impl._M_start + __index;
607
	    iterator __pos1 = __pos;
608
	    ++__pos1;
609
	    _GLIBCXX_MOVE3(__front2, __pos1, __front1);
610
	  }
611
	else
612
	  {
613
	    push_back(_GLIBCXX_MOVE(back()));
614
	    iterator __back1 = this->_M_impl._M_finish;
615
	    --__back1;
616
	    iterator __back2 = __back1;
617
	    --__back2;
618
	    __pos = this->_M_impl._M_start + __index;
619
	    _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
620
	  }
621
	*__pos = _GLIBCXX_MOVE(__x_copy);
622
	return __pos;
623
      }
624
 
625
  template 
626
    void
627
    deque<_Tp, _Alloc>::
628
    _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
629
    {
630
      const difference_type __elems_before = __pos - this->_M_impl._M_start;
631
      const size_type __length = this->size();
632
      value_type __x_copy = __x;
633
      if (__elems_before < difference_type(__length / 2))
634
	{
635
	  iterator __new_start = _M_reserve_elements_at_front(__n);
636
	  iterator __old_start = this->_M_impl._M_start;
637
	  __pos = this->_M_impl._M_start + __elems_before;
638
	  __try
639
	    {
640
	      if (__elems_before >= difference_type(__n))
641
		{
642
		  iterator __start_n = (this->_M_impl._M_start
643
					+ difference_type(__n));
644
		  std::__uninitialized_move_a(this->_M_impl._M_start,
645
					      __start_n, __new_start,
646
					      _M_get_Tp_allocator());
647
		  this->_M_impl._M_start = __new_start;
648
		  _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
649
		  std::fill(__pos - difference_type(__n), __pos, __x_copy);
650
		}
651
	      else
652
		{
653
		  std::__uninitialized_move_fill(this->_M_impl._M_start,
654
						 __pos, __new_start,
655
						 this->_M_impl._M_start,
656
						 __x_copy,
657
						 _M_get_Tp_allocator());
658
		  this->_M_impl._M_start = __new_start;
659
		  std::fill(__old_start, __pos, __x_copy);
660
		}
661
	    }
662
	  __catch(...)
663
	    {
664
	      _M_destroy_nodes(__new_start._M_node,
665
			       this->_M_impl._M_start._M_node);
666
	      __throw_exception_again;
667
	    }
668
	}
669
      else
670
	{
671
	  iterator __new_finish = _M_reserve_elements_at_back(__n);
672
	  iterator __old_finish = this->_M_impl._M_finish;
673
	  const difference_type __elems_after =
674
	    difference_type(__length) - __elems_before;
675
	  __pos = this->_M_impl._M_finish - __elems_after;
676
	  __try
677
	    {
678
	      if (__elems_after > difference_type(__n))
679
		{
680
		  iterator __finish_n = (this->_M_impl._M_finish
681
					 - difference_type(__n));
682
		  std::__uninitialized_move_a(__finish_n,
683
					      this->_M_impl._M_finish,
684
					      this->_M_impl._M_finish,
685
					      _M_get_Tp_allocator());
686
		  this->_M_impl._M_finish = __new_finish;
687
		  _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
688
		  std::fill(__pos, __pos + difference_type(__n), __x_copy);
689
		}
690
	      else
691
		{
692
		  std::__uninitialized_fill_move(this->_M_impl._M_finish,
693
						 __pos + difference_type(__n),
694
						 __x_copy, __pos,
695
						 this->_M_impl._M_finish,
696
						 _M_get_Tp_allocator());
697
		  this->_M_impl._M_finish = __new_finish;
698
		  std::fill(__pos, __old_finish, __x_copy);
699
		}
700
	    }
701
	  __catch(...)
702
	    {
703
	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
704
			       __new_finish._M_node + 1);
705
	      __throw_exception_again;
706
	    }
707
	}
708
    }
709
 
710
  template 
711
    template 
712
      void
713
      deque<_Tp, _Alloc>::
714
      _M_insert_aux(iterator __pos,
715
                    _ForwardIterator __first, _ForwardIterator __last,
716
                    size_type __n)
717
      {
718
        const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
719
        const size_type __length = size();
720
        if (static_cast(__elemsbefore) < __length / 2)
721
	  {
722
	    iterator __new_start = _M_reserve_elements_at_front(__n);
723
	    iterator __old_start = this->_M_impl._M_start;
724
	    __pos = this->_M_impl._M_start + __elemsbefore;
725
	    __try
726
	      {
727
		if (__elemsbefore >= difference_type(__n))
728
		  {
729
		    iterator __start_n = (this->_M_impl._M_start
730
					  + difference_type(__n));
731
		    std::__uninitialized_move_a(this->_M_impl._M_start,
732
						__start_n, __new_start,
733
						_M_get_Tp_allocator());
734
		    this->_M_impl._M_start = __new_start;
735
		    _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
736
		    std::copy(__first, __last, __pos - difference_type(__n));
737
		  }
738
		else
739
		  {
740
		    _ForwardIterator __mid = __first;
741
		    std::advance(__mid, difference_type(__n) - __elemsbefore);
742
		    std::__uninitialized_move_copy(this->_M_impl._M_start,
743
						   __pos, __first, __mid,
744
						   __new_start,
745
						   _M_get_Tp_allocator());
746
		    this->_M_impl._M_start = __new_start;
747
		    std::copy(__mid, __last, __old_start);
748
		  }
749
	      }
750
	    __catch(...)
751
	      {
752
		_M_destroy_nodes(__new_start._M_node,
753
				 this->_M_impl._M_start._M_node);
754
		__throw_exception_again;
755
	      }
756
	  }
757
        else
758
        {
759
          iterator __new_finish = _M_reserve_elements_at_back(__n);
760
          iterator __old_finish = this->_M_impl._M_finish;
761
          const difference_type __elemsafter =
762
            difference_type(__length) - __elemsbefore;
763
          __pos = this->_M_impl._M_finish - __elemsafter;
764
          __try
765
            {
766
              if (__elemsafter > difference_type(__n))
767
		{
768
		  iterator __finish_n = (this->_M_impl._M_finish
769
					 - difference_type(__n));
770
		  std::__uninitialized_move_a(__finish_n,
771
					      this->_M_impl._M_finish,
772
					      this->_M_impl._M_finish,
773
					      _M_get_Tp_allocator());
774
		  this->_M_impl._M_finish = __new_finish;
775
		  _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
776
		  std::copy(__first, __last, __pos);
777
		}
778
              else
779
		{
780
		  _ForwardIterator __mid = __first;
781
		  std::advance(__mid, __elemsafter);
782
		  std::__uninitialized_copy_move(__mid, __last, __pos,
783
						 this->_M_impl._M_finish,
784
						 this->_M_impl._M_finish,
785
						 _M_get_Tp_allocator());
786
		  this->_M_impl._M_finish = __new_finish;
787
		  std::copy(__first, __mid, __pos);
788
		}
789
            }
790
          __catch(...)
791
            {
792
              _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
793
			       __new_finish._M_node + 1);
794
              __throw_exception_again;
795
            }
796
        }
797
      }
798
 
799
   template
800
     void
801
     deque<_Tp, _Alloc>::
802
     _M_destroy_data_aux(iterator __first, iterator __last)
803
     {
804
       for (_Map_pointer __node = __first._M_node + 1;
805
	    __node < __last._M_node; ++__node)
806
	 std::_Destroy(*__node, *__node + _S_buffer_size(),
807
		       _M_get_Tp_allocator());
808
 
809
       if (__first._M_node != __last._M_node)
810
	 {
811
	   std::_Destroy(__first._M_cur, __first._M_last,
812
			 _M_get_Tp_allocator());
813
	   std::_Destroy(__last._M_first, __last._M_cur,
814
			 _M_get_Tp_allocator());
815
	 }
816
       else
817
	 std::_Destroy(__first._M_cur, __last._M_cur,
818
		       _M_get_Tp_allocator());
819
     }
820
 
821
  template 
822
    void
823
    deque<_Tp, _Alloc>::
824
    _M_new_elements_at_front(size_type __new_elems)
825
    {
826
      if (this->max_size() - this->size() < __new_elems)
827
	__throw_length_error(__N("deque::_M_new_elements_at_front"));
828
 
829
      const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
830
				     / _S_buffer_size());
831
      _M_reserve_map_at_front(__new_nodes);
832
      size_type __i;
833
      __try
834
        {
835
          for (__i = 1; __i <= __new_nodes; ++__i)
836
            *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
837
        }
838
      __catch(...)
839
        {
840
          for (size_type __j = 1; __j < __i; ++__j)
841
            _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
842
          __throw_exception_again;
843
        }
844
    }
845
 
846
  template 
847
    void
848
    deque<_Tp, _Alloc>::
849
    _M_new_elements_at_back(size_type __new_elems)
850
    {
851
      if (this->max_size() - this->size() < __new_elems)
852
	__throw_length_error(__N("deque::_M_new_elements_at_back"));
853
 
854
      const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
855
				     / _S_buffer_size());
856
      _M_reserve_map_at_back(__new_nodes);
857
      size_type __i;
858
      __try
859
        {
860
          for (__i = 1; __i <= __new_nodes; ++__i)
861
            *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
862
        }
863
      __catch(...)
864
        {
865
          for (size_type __j = 1; __j < __i; ++__j)
866
            _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
867
          __throw_exception_again;
868
        }
869
    }
870
 
871
  template 
872
    void
873
    deque<_Tp, _Alloc>::
874
    _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
875
    {
876
      const size_type __old_num_nodes
877
	= this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
878
      const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
879
 
880
      _Map_pointer __new_nstart;
881
      if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
882
	{
883
	  __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
884
					 - __new_num_nodes) / 2
885
	                 + (__add_at_front ? __nodes_to_add : 0);
886
	  if (__new_nstart < this->_M_impl._M_start._M_node)
887
	    std::copy(this->_M_impl._M_start._M_node,
888
		      this->_M_impl._M_finish._M_node + 1,
889
		      __new_nstart);
890
	  else
891
	    std::copy_backward(this->_M_impl._M_start._M_node,
892
			       this->_M_impl._M_finish._M_node + 1,
893
			       __new_nstart + __old_num_nodes);
894
	}
895
      else
896
	{
897
	  size_type __new_map_size = this->_M_impl._M_map_size
898
	                             + std::max(this->_M_impl._M_map_size,
899
						__nodes_to_add) + 2;
900
 
901
	  _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
902
	  __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
903
	                 + (__add_at_front ? __nodes_to_add : 0);
904
	  std::copy(this->_M_impl._M_start._M_node,
905
		    this->_M_impl._M_finish._M_node + 1,
906
		    __new_nstart);
907
	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
908
 
909
	  this->_M_impl._M_map = __new_map;
910
	  this->_M_impl._M_map_size = __new_map_size;
911
	}
912
 
913
      this->_M_impl._M_start._M_set_node(__new_nstart);
914
      this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
915
    }
916
 
917
  // Overload for deque::iterators, exploiting the "segmented-iterator
918
  // optimization".
919
  template
920
    void
921
    fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
922
	 const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
923
    {
924
      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
925
 
926
      for (typename _Self::_Map_pointer __node = __first._M_node + 1;
927
           __node < __last._M_node; ++__node)
928
	std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
929
 
930
      if (__first._M_node != __last._M_node)
931
	{
932
	  std::fill(__first._M_cur, __first._M_last, __value);
933
	  std::fill(__last._M_first, __last._M_cur, __value);
934
	}
935
      else
936
	std::fill(__first._M_cur, __last._M_cur, __value);
937
    }
938
 
939
  template
940
    _Deque_iterator<_Tp, _Tp&, _Tp*>
941
    copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
942
	 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
943
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
944
    {
945
      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
946
      typedef typename _Self::difference_type difference_type;
947
 
948
      difference_type __len = __last - __first;
949
      while (__len > 0)
950
	{
951
	  const difference_type __clen
952
	    = std::min(__len, std::min(__first._M_last - __first._M_cur,
953
				       __result._M_last - __result._M_cur));
954
	  std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
955
	  __first += __clen;
956
	  __result += __clen;
957
	  __len -= __clen;
958
	}
959
      return __result;
960
    }
961
 
962
  template
963
    _Deque_iterator<_Tp, _Tp&, _Tp*>
964
    copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
965
		  _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
966
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
967
    {
968
      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
969
      typedef typename _Self::difference_type difference_type;
970
 
971
      difference_type __len = __last - __first;
972
      while (__len > 0)
973
	{
974
	  difference_type __llen = __last._M_cur - __last._M_first;
975
	  _Tp* __lend = __last._M_cur;
976
 
977
	  difference_type __rlen = __result._M_cur - __result._M_first;
978
	  _Tp* __rend = __result._M_cur;
979
 
980
	  if (!__llen)
981
	    {
982
	      __llen = _Self::_S_buffer_size();
983
	      __lend = *(__last._M_node - 1) + __llen;
984
	    }
985
	  if (!__rlen)
986
	    {
987
	      __rlen = _Self::_S_buffer_size();
988
	      __rend = *(__result._M_node - 1) + __rlen;
989
	    }
990
 
991
	  const difference_type __clen = std::min(__len,
992
						  std::min(__llen, __rlen));
993
	  std::copy_backward(__lend - __clen, __lend, __rend);
994
	  __last -= __clen;
995
	  __result -= __clen;
996
	  __len -= __clen;
997
	}
998
      return __result;
999
    }
1000
 
1001
#if __cplusplus >= 201103L
1002
  template
1003
    _Deque_iterator<_Tp, _Tp&, _Tp*>
1004
    move(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
1005
	 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
1006
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1007
    {
1008
      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
1009
      typedef typename _Self::difference_type difference_type;
1010
 
1011
      difference_type __len = __last - __first;
1012
      while (__len > 0)
1013
	{
1014
	  const difference_type __clen
1015
	    = std::min(__len, std::min(__first._M_last - __first._M_cur,
1016
				       __result._M_last - __result._M_cur));
1017
	  std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
1018
	  __first += __clen;
1019
	  __result += __clen;
1020
	  __len -= __clen;
1021
	}
1022
      return __result;
1023
    }
1024
 
1025
  template
1026
    _Deque_iterator<_Tp, _Tp&, _Tp*>
1027
    move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
1028
		  _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
1029
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1030
    {
1031
      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
1032
      typedef typename _Self::difference_type difference_type;
1033
 
1034
      difference_type __len = __last - __first;
1035
      while (__len > 0)
1036
	{
1037
	  difference_type __llen = __last._M_cur - __last._M_first;
1038
	  _Tp* __lend = __last._M_cur;
1039
 
1040
	  difference_type __rlen = __result._M_cur - __result._M_first;
1041
	  _Tp* __rend = __result._M_cur;
1042
 
1043
	  if (!__llen)
1044
	    {
1045
	      __llen = _Self::_S_buffer_size();
1046
	      __lend = *(__last._M_node - 1) + __llen;
1047
	    }
1048
	  if (!__rlen)
1049
	    {
1050
	      __rlen = _Self::_S_buffer_size();
1051
	      __rend = *(__result._M_node - 1) + __rlen;
1052
	    }
1053
 
1054
	  const difference_type __clen = std::min(__len,
1055
						  std::min(__llen, __rlen));
1056
	  std::move_backward(__lend - __clen, __lend, __rend);
1057
	  __last -= __clen;
1058
	  __result -= __clen;
1059
	  __len -= __clen;
1060
	}
1061
      return __result;
1062
    }
1063
#endif
1064
 
1065
_GLIBCXX_END_NAMESPACE_CONTAINER
1066
} // namespace std
1067
 
1068
#endif