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