• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-armeabi-2013.11/arm-none-eabi/include/c++/4.8.1/bits/
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// <http://www.gnu.org/licenses/>.
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
59namespace std _GLIBCXX_VISIBILITY(default)
60{
61_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
62
63#if __cplusplus >= 201103L
64  template <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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<typename _Tp, typename _Alloc>
113    template<typename... _Args>
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<typename _Tp, typename _Alloc>
129    template<typename... _Args>
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 <typename _Tp, typename _Alloc>
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<typename _Tp, typename _Alloc>
169    template<typename... _Args>
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 <typename _Tp, typename _Alloc>
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<size_type>(__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 <typename _Tp, typename _Alloc>
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<size_type>(__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 <typename _Tp, class _Alloc>
247    template <typename _InputIterator>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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<deque>::_S_do_it(*this);
345    }
346#endif
347
348  template <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
374    template <typename _InputIterator>
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 <typename _Tp, typename _Alloc>
398    template <typename _ForwardIterator>
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<typename _Tp, typename _Alloc>
435#if __cplusplus >= 201103L
436    template<typename... _Args>
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<typename _Tp, typename _Alloc>
469#if __cplusplus >= 201103L
470    template<typename... _Args>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
529    template <typename _InputIterator>
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 <typename _Tp, typename _Alloc>
538    template <typename _ForwardIterator>
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<typename _Tp, typename _Alloc>
584#if __cplusplus >= 201103L
585    template<typename... _Args>
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<size_type>(__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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
711    template <typename _ForwardIterator>
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<size_type>(__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<typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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 <typename _Tp, typename _Alloc>
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<typename _Tp>
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<typename _Tp>
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<typename _Tp>
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<typename _Tp>
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<typename _Tp>
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
1069