xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/deque.tcc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 // Deque implementation (out of line) -*- C++ -*-
2 
3 // Copyright (C) 2001-2022 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 #include <bits/stl_algobase.h>
60 
61 namespace std _GLIBCXX_VISIBILITY(default)
62 {
63 _GLIBCXX_BEGIN_NAMESPACE_VERSION
64 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
65 
66 #if __cplusplus >= 201103L
67   template <typename _Tp, typename _Alloc>
68     void
69     deque<_Tp, _Alloc>::
_M_default_initialize()70     _M_default_initialize()
71     {
72       _Map_pointer __cur;
73       __try
74 	{
75 	  for (__cur = this->_M_impl._M_start._M_node;
76 	       __cur < this->_M_impl._M_finish._M_node;
77 	       ++__cur)
78 	    std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
79 					   _M_get_Tp_allocator());
80 	  std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
81 					 this->_M_impl._M_finish._M_cur,
82 					 _M_get_Tp_allocator());
83 	}
84       __catch(...)
85 	{
86 	  std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
87 			_M_get_Tp_allocator());
88 	  __throw_exception_again;
89 	}
90     }
91 #endif
92 
93   template <typename _Tp, typename _Alloc>
94     deque<_Tp, _Alloc>&
95     deque<_Tp, _Alloc>::
operator =(const deque & __x)96     operator=(const deque& __x)
97     {
98       if (std::__addressof(__x) != this)
99 	{
100 #if __cplusplus >= 201103L
101 	  if (_Alloc_traits::_S_propagate_on_copy_assign())
102 	    {
103 	      if (!_Alloc_traits::_S_always_equal()
104 		  && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
105 		{
106 		  // Replacement allocator cannot free existing storage,
107 		  // so deallocate everything and take copy of __x's data.
108 		  _M_replace_map(__x, __x.get_allocator());
109 		  std::__alloc_on_copy(_M_get_Tp_allocator(),
110 				       __x._M_get_Tp_allocator());
111 		  return *this;
112 		}
113 	      std::__alloc_on_copy(_M_get_Tp_allocator(),
114 				   __x._M_get_Tp_allocator());
115 	    }
116 #endif
117 	  const size_type __len = size();
118 	  if (__len >= __x.size())
119 	    _M_erase_at_end(std::copy(__x.begin(), __x.end(),
120 				      this->_M_impl._M_start));
121 	  else
122 	    {
123 	      const_iterator __mid = __x.begin() + difference_type(__len);
124 	      std::copy(__x.begin(), __mid, this->_M_impl._M_start);
125 	      _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(),
126 				  std::random_access_iterator_tag());
127 	    }
128 	}
129       return *this;
130     }
131 
132 #if __cplusplus >= 201103L
133   template<typename _Tp, typename _Alloc>
134     template<typename... _Args>
135 #if __cplusplus > 201402L
136       typename deque<_Tp, _Alloc>::reference
137 #else
138       void
139 #endif
140       deque<_Tp, _Alloc>::
emplace_front(_Args &&...__args)141       emplace_front(_Args&&... __args)
142       {
143 	if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
144 	  {
145 	    _Alloc_traits::construct(this->_M_impl,
146 				     this->_M_impl._M_start._M_cur - 1,
147 				     std::forward<_Args>(__args)...);
148 	    --this->_M_impl._M_start._M_cur;
149 	  }
150 	else
151 	  _M_push_front_aux(std::forward<_Args>(__args)...);
152 #if __cplusplus > 201402L
153 	return front();
154 #endif
155       }
156 
157   template<typename _Tp, typename _Alloc>
158     template<typename... _Args>
159 #if __cplusplus > 201402L
160       typename deque<_Tp, _Alloc>::reference
161 #else
162       void
163 #endif
164       deque<_Tp, _Alloc>::
emplace_back(_Args &&...__args)165       emplace_back(_Args&&... __args)
166       {
167 	if (this->_M_impl._M_finish._M_cur
168 	    != this->_M_impl._M_finish._M_last - 1)
169 	  {
170 	    _Alloc_traits::construct(this->_M_impl,
171 				     this->_M_impl._M_finish._M_cur,
172 				     std::forward<_Args>(__args)...);
173 	    ++this->_M_impl._M_finish._M_cur;
174 	  }
175 	else
176 	  _M_push_back_aux(std::forward<_Args>(__args)...);
177 #if __cplusplus > 201402L
178 	return back();
179 #endif
180       }
181 #endif
182 
183 #if __cplusplus >= 201103L
184   template<typename _Tp, typename _Alloc>
185     template<typename... _Args>
186       typename deque<_Tp, _Alloc>::iterator
187       deque<_Tp, _Alloc>::
emplace(const_iterator __position,_Args &&...__args)188       emplace(const_iterator __position, _Args&&... __args)
189       {
190 	if (__position._M_cur == this->_M_impl._M_start._M_cur)
191 	  {
192 	    emplace_front(std::forward<_Args>(__args)...);
193 	    return this->_M_impl._M_start;
194 	  }
195 	else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
196 	  {
197 	    emplace_back(std::forward<_Args>(__args)...);
198 	    iterator __tmp = this->_M_impl._M_finish;
199 	    --__tmp;
200 	    return __tmp;
201 	  }
202 	else
203 	  return _M_insert_aux(__position._M_const_cast(),
204 			       std::forward<_Args>(__args)...);
205       }
206 #endif
207 
208   template <typename _Tp, typename _Alloc>
209     typename deque<_Tp, _Alloc>::iterator
210     deque<_Tp, _Alloc>::
211 #if __cplusplus >= 201103L
insert(const_iterator __position,const value_type & __x)212     insert(const_iterator __position, const value_type& __x)
213 #else
214     insert(iterator __position, const value_type& __x)
215 #endif
216     {
217       if (__position._M_cur == this->_M_impl._M_start._M_cur)
218 	{
219 	  push_front(__x);
220 	  return this->_M_impl._M_start;
221 	}
222       else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
223 	{
224 	  push_back(__x);
225 	  iterator __tmp = this->_M_impl._M_finish;
226 	  --__tmp;
227 	  return __tmp;
228 	}
229       else
230 	return _M_insert_aux(__position._M_const_cast(), __x);
231    }
232 
233   template <typename _Tp, typename _Alloc>
234     typename deque<_Tp, _Alloc>::iterator
235     deque<_Tp, _Alloc>::
_M_erase(iterator __position)236     _M_erase(iterator __position)
237     {
238       iterator __next = __position;
239       ++__next;
240       const difference_type __index = __position - begin();
241       if (static_cast<size_type>(__index) < (size() >> 1))
242 	{
243 	  if (__position != begin())
244 	    _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
245 	  pop_front();
246 	}
247       else
248 	{
249 	  if (__next != end())
250 	    _GLIBCXX_MOVE3(__next, end(), __position);
251 	  pop_back();
252 	}
253       return begin() + __index;
254     }
255 
256   template <typename _Tp, typename _Alloc>
257     typename deque<_Tp, _Alloc>::iterator
258     deque<_Tp, _Alloc>::
_M_erase(iterator __first,iterator __last)259     _M_erase(iterator __first, iterator __last)
260     {
261       if (__first == __last)
262 	return __first;
263       else if (__first == begin() && __last == end())
264 	{
265 	  clear();
266 	  return end();
267 	}
268       else
269 	{
270 	  const difference_type __n = __last - __first;
271 	  const difference_type __elems_before = __first - begin();
272 	  if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
273 	    {
274 	      if (__first != begin())
275 		_GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
276 	      _M_erase_at_begin(begin() + __n);
277 	    }
278 	  else
279 	    {
280 	      if (__last != end())
281 		_GLIBCXX_MOVE3(__last, end(), __first);
282 	      _M_erase_at_end(end() - __n);
283 	    }
284 	  return begin() + __elems_before;
285 	}
286     }
287 
288   template <typename _Tp, class _Alloc>
289     template <typename _InputIterator>
290       void
291       deque<_Tp, _Alloc>::
_M_assign_aux(_InputIterator __first,_InputIterator __last,std::input_iterator_tag)292       _M_assign_aux(_InputIterator __first, _InputIterator __last,
293 		    std::input_iterator_tag)
294       {
295 	iterator __cur = begin();
296 	for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
297 	  *__cur = *__first;
298 	if (__first == __last)
299 	  _M_erase_at_end(__cur);
300 	else
301 	  _M_range_insert_aux(end(), __first, __last,
302 			      std::__iterator_category(__first));
303       }
304 
305   template <typename _Tp, typename _Alloc>
306     void
307     deque<_Tp, _Alloc>::
_M_fill_insert(iterator __pos,size_type __n,const value_type & __x)308     _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
309     {
310       if (__pos._M_cur == this->_M_impl._M_start._M_cur)
311 	{
312 	  iterator __new_start = _M_reserve_elements_at_front(__n);
313 	  __try
314 	    {
315 	      std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
316 					  __x, _M_get_Tp_allocator());
317 	      this->_M_impl._M_start = __new_start;
318 	    }
319 	  __catch(...)
320 	    {
321 	      _M_destroy_nodes(__new_start._M_node,
322 			       this->_M_impl._M_start._M_node);
323 	      __throw_exception_again;
324 	    }
325 	}
326       else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
327 	{
328 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
329 	  __try
330 	    {
331 	      std::__uninitialized_fill_a(this->_M_impl._M_finish,
332 					  __new_finish, __x,
333 					  _M_get_Tp_allocator());
334 	      this->_M_impl._M_finish = __new_finish;
335 	    }
336 	  __catch(...)
337 	    {
338 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
339 			       __new_finish._M_node + 1);
340 	      __throw_exception_again;
341 	    }
342 	}
343       else
344 	_M_insert_aux(__pos, __n, __x);
345     }
346 
347 #if __cplusplus >= 201103L
348   template <typename _Tp, typename _Alloc>
349     void
350     deque<_Tp, _Alloc>::
_M_default_append(size_type __n)351     _M_default_append(size_type __n)
352     {
353       if (__n)
354 	{
355 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
356 	  __try
357 	    {
358 	      std::__uninitialized_default_a(this->_M_impl._M_finish,
359 					     __new_finish,
360 					     _M_get_Tp_allocator());
361 	      this->_M_impl._M_finish = __new_finish;
362 	    }
363 	  __catch(...)
364 	    {
365 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
366 			       __new_finish._M_node + 1);
367 	      __throw_exception_again;
368 	    }
369 	}
370     }
371 
372   template <typename _Tp, typename _Alloc>
373     bool
374     deque<_Tp, _Alloc>::
_M_shrink_to_fit()375     _M_shrink_to_fit()
376     {
377       const difference_type __front_capacity
378 	= (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
379       if (__front_capacity == 0)
380 	return false;
381 
382       const difference_type __back_capacity
383 	= (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
384       if (__front_capacity + __back_capacity < _S_buffer_size())
385 	return false;
386 
387       return std::__shrink_to_fit_aux<deque>::_S_do_it(*this);
388     }
389 #endif
390 
391   template <typename _Tp, typename _Alloc>
392     void
393     deque<_Tp, _Alloc>::
_M_fill_initialize(const value_type & __value)394     _M_fill_initialize(const value_type& __value)
395     {
396       _Map_pointer __cur;
397       __try
398 	{
399 	  for (__cur = this->_M_impl._M_start._M_node;
400 	       __cur < this->_M_impl._M_finish._M_node;
401 	       ++__cur)
402 	    std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
403 					__value, _M_get_Tp_allocator());
404 	  std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
405 				      this->_M_impl._M_finish._M_cur,
406 				      __value, _M_get_Tp_allocator());
407 	}
408       __catch(...)
409 	{
410 	  std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
411 			_M_get_Tp_allocator());
412 	  __throw_exception_again;
413 	}
414     }
415 
416   template <typename _Tp, typename _Alloc>
417     template <typename _InputIterator>
418       void
419       deque<_Tp, _Alloc>::
_M_range_initialize(_InputIterator __first,_InputIterator __last,std::input_iterator_tag)420       _M_range_initialize(_InputIterator __first, _InputIterator __last,
421 			  std::input_iterator_tag)
422       {
423 	this->_M_initialize_map(0);
424 	__try
425 	  {
426 	    for (; __first != __last; ++__first)
427 #if __cplusplus >= 201103L
428 	      emplace_back(*__first);
429 #else
430 	      push_back(*__first);
431 #endif
432 	  }
433 	__catch(...)
434 	  {
435 	    clear();
436 	    __throw_exception_again;
437 	  }
438       }
439 
440   template <typename _Tp, typename _Alloc>
441     template <typename _ForwardIterator>
442       void
443       deque<_Tp, _Alloc>::
_M_range_initialize(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)444       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
445 			  std::forward_iterator_tag)
446       {
447 	const size_type __n = std::distance(__first, __last);
448 	this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
449 
450 	_Map_pointer __cur_node;
451 	__try
452 	  {
453 	    for (__cur_node = this->_M_impl._M_start._M_node;
454 		 __cur_node < this->_M_impl._M_finish._M_node;
455 		 ++__cur_node)
456 	      {
457 		if (__n < _S_buffer_size())
458 		  __builtin_unreachable(); // See PR 100516
459 
460 		_ForwardIterator __mid = __first;
461 		std::advance(__mid, _S_buffer_size());
462 		std::__uninitialized_copy_a(__first, __mid, *__cur_node,
463 					    _M_get_Tp_allocator());
464 		__first = __mid;
465 	      }
466 	    std::__uninitialized_copy_a(__first, __last,
467 					this->_M_impl._M_finish._M_first,
468 					_M_get_Tp_allocator());
469 	  }
470 	__catch(...)
471 	  {
472 	    std::_Destroy(this->_M_impl._M_start,
473 			  iterator(*__cur_node, __cur_node),
474 			  _M_get_Tp_allocator());
475 	    __throw_exception_again;
476 	  }
477       }
478 
479   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
480   template<typename _Tp, typename _Alloc>
481 #if __cplusplus >= 201103L
482     template<typename... _Args>
483       void
484       deque<_Tp, _Alloc>::
_M_push_back_aux(_Args &&...__args)485       _M_push_back_aux(_Args&&... __args)
486 #else
487       void
488       deque<_Tp, _Alloc>::
489       _M_push_back_aux(const value_type& __t)
490 #endif
491       {
492 	if (size() == max_size())
493 	  __throw_length_error(
494 	      __N("cannot create std::deque larger than max_size()"));
495 
496 	_M_reserve_map_at_back();
497 	*(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
498 	__try
499 	  {
500 #if __cplusplus >= 201103L
501 	    _Alloc_traits::construct(this->_M_impl,
502 				     this->_M_impl._M_finish._M_cur,
503 				     std::forward<_Args>(__args)...);
504 #else
505 	    this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
506 #endif
507 	    this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
508 						+ 1);
509 	    this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
510 	  }
511 	__catch(...)
512 	  {
513 	    _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
514 	    __throw_exception_again;
515 	  }
516       }
517 
518   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
519   template<typename _Tp, typename _Alloc>
520 #if __cplusplus >= 201103L
521     template<typename... _Args>
522       void
523       deque<_Tp, _Alloc>::
_M_push_front_aux(_Args &&...__args)524       _M_push_front_aux(_Args&&... __args)
525 #else
526       void
527       deque<_Tp, _Alloc>::
528       _M_push_front_aux(const value_type& __t)
529 #endif
530       {
531 	if (size() == max_size())
532 	  __throw_length_error(
533 	      __N("cannot create std::deque larger than max_size()"));
534 
535 	_M_reserve_map_at_front();
536 	*(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
537 	__try
538 	  {
539 	    this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
540 					       - 1);
541 	    this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
542 #if __cplusplus >= 201103L
543 	    _Alloc_traits::construct(this->_M_impl,
544 				     this->_M_impl._M_start._M_cur,
545 				     std::forward<_Args>(__args)...);
546 #else
547 	    this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
548 #endif
549 	  }
550 	__catch(...)
551 	  {
552 	    ++this->_M_impl._M_start;
553 	    _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
554 	    __throw_exception_again;
555 	  }
556       }
557 
558   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
559   template <typename _Tp, typename _Alloc>
560     void deque<_Tp, _Alloc>::
_M_pop_back_aux()561     _M_pop_back_aux()
562     {
563       _M_deallocate_node(this->_M_impl._M_finish._M_first);
564       this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
565       this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
566       _Alloc_traits::destroy(_M_get_Tp_allocator(),
567 			     this->_M_impl._M_finish._M_cur);
568     }
569 
570   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
571   // Note that if the deque has at least one element (a precondition for this
572   // member function), and if
573   //   _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
574   // then the deque must have at least two nodes.
575   template <typename _Tp, typename _Alloc>
576     void deque<_Tp, _Alloc>::
_M_pop_front_aux()577     _M_pop_front_aux()
578     {
579       _Alloc_traits::destroy(_M_get_Tp_allocator(),
580 			     this->_M_impl._M_start._M_cur);
581       _M_deallocate_node(this->_M_impl._M_start._M_first);
582       this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
583       this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
584     }
585 
586   template <typename _Tp, typename _Alloc>
587     template <typename _InputIterator>
588       void
589       deque<_Tp, _Alloc>::
_M_range_insert_aux(iterator __pos,_InputIterator __first,_InputIterator __last,std::input_iterator_tag)590       _M_range_insert_aux(iterator __pos,
591 			  _InputIterator __first, _InputIterator __last,
592 			  std::input_iterator_tag)
593       { std::copy(__first, __last, std::inserter(*this, __pos)); }
594 
595   template <typename _Tp, typename _Alloc>
596     template <typename _ForwardIterator>
597       void
598       deque<_Tp, _Alloc>::
_M_range_insert_aux(iterator __pos,_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)599       _M_range_insert_aux(iterator __pos,
600 			  _ForwardIterator __first, _ForwardIterator __last,
601 			  std::forward_iterator_tag)
602       {
603 	const size_type __n = std::distance(__first, __last);
604 	if (__pos._M_cur == this->_M_impl._M_start._M_cur)
605 	  {
606 	    iterator __new_start = _M_reserve_elements_at_front(__n);
607 	    __try
608 	      {
609 		std::__uninitialized_copy_a(__first, __last, __new_start,
610 					    _M_get_Tp_allocator());
611 		this->_M_impl._M_start = __new_start;
612 	      }
613 	    __catch(...)
614 	      {
615 		_M_destroy_nodes(__new_start._M_node,
616 				 this->_M_impl._M_start._M_node);
617 		__throw_exception_again;
618 	      }
619 	  }
620 	else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
621 	  {
622 	    iterator __new_finish = _M_reserve_elements_at_back(__n);
623 	    __try
624 	      {
625 		std::__uninitialized_copy_a(__first, __last,
626 					    this->_M_impl._M_finish,
627 					    _M_get_Tp_allocator());
628 		this->_M_impl._M_finish = __new_finish;
629 	      }
630 	    __catch(...)
631 	      {
632 		_M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
633 				 __new_finish._M_node + 1);
634 		__throw_exception_again;
635 	      }
636 	  }
637 	else
638 	  _M_insert_aux(__pos, __first, __last, __n);
639       }
640 
641   template<typename _Tp, typename _Alloc>
642 #if __cplusplus >= 201103L
643     template<typename... _Args>
644       typename deque<_Tp, _Alloc>::iterator
645       deque<_Tp, _Alloc>::
_M_insert_aux(iterator __pos,_Args &&...__args)646       _M_insert_aux(iterator __pos, _Args&&... __args)
647       {
648 	value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
649 #else
650     typename deque<_Tp, _Alloc>::iterator
651       deque<_Tp, _Alloc>::
652       _M_insert_aux(iterator __pos, const value_type& __x)
653       {
654 	value_type __x_copy = __x; // XXX copy
655 #endif
656 	difference_type __index = __pos - this->_M_impl._M_start;
657 	if (static_cast<size_type>(__index) < size() / 2)
658 	  {
659 	    push_front(_GLIBCXX_MOVE(front()));
660 	    iterator __front1 = this->_M_impl._M_start;
661 	    ++__front1;
662 	    iterator __front2 = __front1;
663 	    ++__front2;
664 	    __pos = this->_M_impl._M_start + __index;
665 	    iterator __pos1 = __pos;
666 	    ++__pos1;
667 	    _GLIBCXX_MOVE3(__front2, __pos1, __front1);
668 	  }
669 	else
670 	  {
671 	    push_back(_GLIBCXX_MOVE(back()));
672 	    iterator __back1 = this->_M_impl._M_finish;
673 	    --__back1;
674 	    iterator __back2 = __back1;
675 	    --__back2;
676 	    __pos = this->_M_impl._M_start + __index;
677 	    _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
678 	  }
679 	*__pos = _GLIBCXX_MOVE(__x_copy);
680 	return __pos;
681       }
682 
683   template <typename _Tp, typename _Alloc>
684     void
685     deque<_Tp, _Alloc>::
686     _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
687     {
688       const difference_type __elems_before = __pos - this->_M_impl._M_start;
689       const size_type __length = this->size();
690       value_type __x_copy = __x;
691       if (__elems_before < difference_type(__length / 2))
692 	{
693 	  iterator __new_start = _M_reserve_elements_at_front(__n);
694 	  iterator __old_start = this->_M_impl._M_start;
695 	  __pos = this->_M_impl._M_start + __elems_before;
696 	  __try
697 	    {
698 	      if (__elems_before >= difference_type(__n))
699 		{
700 		  iterator __start_n = (this->_M_impl._M_start
701 					+ difference_type(__n));
702 		  std::__uninitialized_move_a(this->_M_impl._M_start,
703 					      __start_n, __new_start,
704 					      _M_get_Tp_allocator());
705 		  this->_M_impl._M_start = __new_start;
706 		  _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
707 		  std::fill(__pos - difference_type(__n), __pos, __x_copy);
708 		}
709 	      else
710 		{
711 		  std::__uninitialized_move_fill(this->_M_impl._M_start,
712 						 __pos, __new_start,
713 						 this->_M_impl._M_start,
714 						 __x_copy,
715 						 _M_get_Tp_allocator());
716 		  this->_M_impl._M_start = __new_start;
717 		  std::fill(__old_start, __pos, __x_copy);
718 		}
719 	    }
720 	  __catch(...)
721 	    {
722 	      _M_destroy_nodes(__new_start._M_node,
723 			       this->_M_impl._M_start._M_node);
724 	      __throw_exception_again;
725 	    }
726 	}
727       else
728 	{
729 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
730 	  iterator __old_finish = this->_M_impl._M_finish;
731 	  const difference_type __elems_after =
732 	    difference_type(__length) - __elems_before;
733 	  __pos = this->_M_impl._M_finish - __elems_after;
734 	  __try
735 	    {
736 	      if (__elems_after > difference_type(__n))
737 		{
738 		  iterator __finish_n = (this->_M_impl._M_finish
739 					 - difference_type(__n));
740 		  std::__uninitialized_move_a(__finish_n,
741 					      this->_M_impl._M_finish,
742 					      this->_M_impl._M_finish,
743 					      _M_get_Tp_allocator());
744 		  this->_M_impl._M_finish = __new_finish;
745 		  _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
746 		  std::fill(__pos, __pos + difference_type(__n), __x_copy);
747 		}
748 	      else
749 		{
750 		  std::__uninitialized_fill_move(this->_M_impl._M_finish,
751 						 __pos + difference_type(__n),
752 						 __x_copy, __pos,
753 						 this->_M_impl._M_finish,
754 						 _M_get_Tp_allocator());
755 		  this->_M_impl._M_finish = __new_finish;
756 		  std::fill(__pos, __old_finish, __x_copy);
757 		}
758 	    }
759 	  __catch(...)
760 	    {
761 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
762 			       __new_finish._M_node + 1);
763 	      __throw_exception_again;
764 	    }
765 	}
766     }
767 
768   template <typename _Tp, typename _Alloc>
769     template <typename _ForwardIterator>
770       void
771       deque<_Tp, _Alloc>::
772       _M_insert_aux(iterator __pos,
773 		    _ForwardIterator __first, _ForwardIterator __last,
774 		    size_type __n)
775       {
776 	const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
777 	const size_type __length = size();
778 	if (static_cast<size_type>(__elemsbefore) < __length / 2)
779 	  {
780 	    iterator __new_start = _M_reserve_elements_at_front(__n);
781 	    iterator __old_start = this->_M_impl._M_start;
782 	    __pos = this->_M_impl._M_start + __elemsbefore;
783 	    __try
784 	      {
785 		if (__elemsbefore >= difference_type(__n))
786 		  {
787 		    iterator __start_n = (this->_M_impl._M_start
788 					  + difference_type(__n));
789 		    std::__uninitialized_move_a(this->_M_impl._M_start,
790 						__start_n, __new_start,
791 						_M_get_Tp_allocator());
792 		    this->_M_impl._M_start = __new_start;
793 		    _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
794 		    std::copy(__first, __last, __pos - difference_type(__n));
795 		  }
796 		else
797 		  {
798 		    _ForwardIterator __mid = __first;
799 		    std::advance(__mid, difference_type(__n) - __elemsbefore);
800 		    std::__uninitialized_move_copy(this->_M_impl._M_start,
801 						   __pos, __first, __mid,
802 						   __new_start,
803 						   _M_get_Tp_allocator());
804 		    this->_M_impl._M_start = __new_start;
805 		    std::copy(__mid, __last, __old_start);
806 		  }
807 	      }
808 	    __catch(...)
809 	      {
810 		_M_destroy_nodes(__new_start._M_node,
811 				 this->_M_impl._M_start._M_node);
812 		__throw_exception_again;
813 	      }
814 	  }
815 	else
816 	{
817 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
818 	  iterator __old_finish = this->_M_impl._M_finish;
819 	  const difference_type __elemsafter =
820 	    difference_type(__length) - __elemsbefore;
821 	  __pos = this->_M_impl._M_finish - __elemsafter;
822 	  __try
823 	    {
824 	      if (__elemsafter > difference_type(__n))
825 		{
826 		  iterator __finish_n = (this->_M_impl._M_finish
827 					 - difference_type(__n));
828 		  std::__uninitialized_move_a(__finish_n,
829 					      this->_M_impl._M_finish,
830 					      this->_M_impl._M_finish,
831 					      _M_get_Tp_allocator());
832 		  this->_M_impl._M_finish = __new_finish;
833 		  _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
834 		  std::copy(__first, __last, __pos);
835 		}
836 	      else
837 		{
838 		  _ForwardIterator __mid = __first;
839 		  std::advance(__mid, __elemsafter);
840 		  std::__uninitialized_copy_move(__mid, __last, __pos,
841 						 this->_M_impl._M_finish,
842 						 this->_M_impl._M_finish,
843 						 _M_get_Tp_allocator());
844 		  this->_M_impl._M_finish = __new_finish;
845 		  std::copy(__first, __mid, __pos);
846 		}
847 	    }
848 	  __catch(...)
849 	    {
850 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
851 			       __new_finish._M_node + 1);
852 	      __throw_exception_again;
853 	    }
854 	}
855       }
856 
857    template<typename _Tp, typename _Alloc>
858      void
859      deque<_Tp, _Alloc>::
860      _M_destroy_data_aux(iterator __first, iterator __last)
861      {
862        for (_Map_pointer __node = __first._M_node + 1;
863 	    __node < __last._M_node; ++__node)
864 	 std::_Destroy(*__node, *__node + _S_buffer_size(),
865 		       _M_get_Tp_allocator());
866 
867        if (__first._M_node != __last._M_node)
868 	 {
869 	   std::_Destroy(__first._M_cur, __first._M_last,
870 			 _M_get_Tp_allocator());
871 	   std::_Destroy(__last._M_first, __last._M_cur,
872 			 _M_get_Tp_allocator());
873 	 }
874        else
875 	 std::_Destroy(__first._M_cur, __last._M_cur,
876 		       _M_get_Tp_allocator());
877      }
878 
879   template <typename _Tp, typename _Alloc>
880     void
881     deque<_Tp, _Alloc>::
882     _M_new_elements_at_front(size_type __new_elems)
883     {
884       if (this->max_size() - this->size() < __new_elems)
885 	__throw_length_error(__N("deque::_M_new_elements_at_front"));
886 
887       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
888 				     / _S_buffer_size());
889       _M_reserve_map_at_front(__new_nodes);
890       size_type __i;
891       __try
892 	{
893 	  for (__i = 1; __i <= __new_nodes; ++__i)
894 	    *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
895 	}
896       __catch(...)
897 	{
898 	  for (size_type __j = 1; __j < __i; ++__j)
899 	    _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
900 	  __throw_exception_again;
901 	}
902     }
903 
904   template <typename _Tp, typename _Alloc>
905     void
906     deque<_Tp, _Alloc>::
907     _M_new_elements_at_back(size_type __new_elems)
908     {
909       if (this->max_size() - this->size() < __new_elems)
910 	__throw_length_error(__N("deque::_M_new_elements_at_back"));
911 
912       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
913 				     / _S_buffer_size());
914       _M_reserve_map_at_back(__new_nodes);
915       size_type __i;
916       __try
917 	{
918 	  for (__i = 1; __i <= __new_nodes; ++__i)
919 	    *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
920 	}
921       __catch(...)
922 	{
923 	  for (size_type __j = 1; __j < __i; ++__j)
924 	    _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
925 	  __throw_exception_again;
926 	}
927     }
928 
929   template <typename _Tp, typename _Alloc>
930     void
931     deque<_Tp, _Alloc>::
932     _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
933     {
934       const size_type __old_num_nodes
935 	= this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
936       const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
937 
938       _Map_pointer __new_nstart;
939       if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
940 	{
941 	  __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
942 					 - __new_num_nodes) / 2
943 			 + (__add_at_front ? __nodes_to_add : 0);
944 	  if (__new_nstart < this->_M_impl._M_start._M_node)
945 	    std::copy(this->_M_impl._M_start._M_node,
946 		      this->_M_impl._M_finish._M_node + 1,
947 		      __new_nstart);
948 	  else
949 	    std::copy_backward(this->_M_impl._M_start._M_node,
950 			       this->_M_impl._M_finish._M_node + 1,
951 			       __new_nstart + __old_num_nodes);
952 	}
953       else
954 	{
955 	  size_type __new_map_size = this->_M_impl._M_map_size
956 				     + std::max(this->_M_impl._M_map_size,
957 						__nodes_to_add) + 2;
958 
959 	  _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
960 	  __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
961 			 + (__add_at_front ? __nodes_to_add : 0);
962 	  std::copy(this->_M_impl._M_start._M_node,
963 		    this->_M_impl._M_finish._M_node + 1,
964 		    __new_nstart);
965 	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
966 
967 	  this->_M_impl._M_map = __new_map;
968 	  this->_M_impl._M_map_size = __new_map_size;
969 	}
970 
971       this->_M_impl._M_start._M_set_node(__new_nstart);
972       this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
973     }
974 
975 _GLIBCXX_END_NAMESPACE_CONTAINER
976 
977   // Overload for deque::iterators, exploiting the "segmented-iterator
978   // optimization".
979   template<typename _Tp, typename _VTp>
980     void
981     __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
982 	      const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __last,
983 	      const _VTp& __value)
984     {
985       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
986       if (__first._M_node != __last._M_node)
987 	{
988 	  std::__fill_a1(__first._M_cur, __first._M_last, __value);
989 
990 	  for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
991 	       __node < __last._M_node; ++__node)
992 	    std::__fill_a1(*__node, *__node + _Iter::_S_buffer_size(), __value);
993 
994 	  std::__fill_a1(__last._M_first, __last._M_cur, __value);
995 	}
996       else
997 	std::__fill_a1(__first._M_cur, __last._M_cur, __value);
998     }
999 
1000   template<bool _IsMove,
1001 	   typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1002     _OI
1003     __copy_move_dit(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1004 		    _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1005 		    _OI __result)
1006     {
1007       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1008       if (__first._M_node != __last._M_node)
1009 	{
1010 	  __result
1011 	    = std::__copy_move_a1<_IsMove>(__first._M_cur, __first._M_last,
1012 					   __result);
1013 
1014 	  for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
1015 	       __node != __last._M_node; ++__node)
1016 	    __result
1017 	      = std::__copy_move_a1<_IsMove>(*__node,
1018 					     *__node + _Iter::_S_buffer_size(),
1019 					     __result);
1020 
1021 	  return std::__copy_move_a1<_IsMove>(__last._M_first, __last._M_cur,
1022 					      __result);
1023 	}
1024 
1025       return std::__copy_move_a1<_IsMove>(__first._M_cur, __last._M_cur,
1026 					  __result);
1027     }
1028 
1029   template<bool _IsMove,
1030 	   typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1031     _OI
1032     __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1033 		   _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1034 		   _OI __result)
1035     { return __copy_move_dit<_IsMove>(__first, __last, __result); }
1036 
1037   template<bool _IsMove,
1038 	   typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
1039     _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1040     __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1041 		   _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1042 		   _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
1043     { return __copy_move_dit<_IsMove>(__first, __last, __result); }
1044 
1045   template<bool _IsMove, typename _II, typename _Tp>
1046     typename __gnu_cxx::__enable_if<
1047       __is_random_access_iter<_II>::__value,
1048       _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
1049     __copy_move_a1(_II __first, _II __last,
1050 		   _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1051     {
1052       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
1053       typedef typename _Iter::difference_type difference_type;
1054 
1055       difference_type __len = __last - __first;
1056       while (__len > 0)
1057 	{
1058 	  const difference_type __clen
1059 	    = std::min(__len, __result._M_last - __result._M_cur);
1060 	  std::__copy_move_a1<_IsMove>(__first, __first + __clen,
1061 				       __result._M_cur);
1062 
1063 	  __first += __clen;
1064 	  __result += __clen;
1065 	  __len -= __clen;
1066 	}
1067 
1068       return __result;
1069     }
1070 
1071   template<bool _IsMove, typename _CharT>
1072     typename __gnu_cxx::__enable_if<
1073       __is_char<_CharT>::__value,
1074       _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type
1075     __copy_move_a2(
1076 	istreambuf_iterator<_CharT, char_traits<_CharT> > __first,
1077 	istreambuf_iterator<_CharT, char_traits<_CharT> > __last,
1078 	_GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result)
1079     {
1080       if (__first == __last)
1081 	return __result;
1082 
1083       for (;;)
1084 	{
1085 	  const std::ptrdiff_t __len = __result._M_last - __result._M_cur;
1086 	  const std::ptrdiff_t __nb
1087 	    = std::__copy_n_a(__first, __len, __result._M_cur, false)
1088 	    - __result._M_cur;
1089 	  __result += __nb;
1090 
1091 	  if (__nb != __len)
1092 	    break;
1093 	}
1094 
1095       return __result;
1096     }
1097 
1098   template<typename _CharT, typename _Size>
1099     typename __gnu_cxx::__enable_if<
1100       __is_char<_CharT>::__value,
1101       _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type
1102     __copy_n_a(
1103       istreambuf_iterator<_CharT, char_traits<_CharT> > __it, _Size __size,
1104       _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result,
1105       bool __strict)
1106     {
1107       if (__size == 0)
1108 	return __result;
1109 
1110       do
1111 	{
1112 	  const _Size __len
1113 	    = std::min<_Size>(__result._M_last - __result._M_cur, __size);
1114 	  std::__copy_n_a(__it, __len, __result._M_cur, __strict);
1115 	  __result += __len;
1116 	  __size -= __len;
1117 	}
1118       while (__size != 0);
1119       return __result;
1120     }
1121 
1122   template<bool _IsMove,
1123 	   typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1124     _OI
1125     __copy_move_backward_dit(
1126 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1127 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1128 		_OI __result)
1129     {
1130       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1131       if (__first._M_node != __last._M_node)
1132 	{
1133 	  __result = std::__copy_move_backward_a1<_IsMove>(
1134 		__last._M_first, __last._M_cur, __result);
1135 
1136 	  for (typename _Iter::_Map_pointer __node = __last._M_node - 1;
1137 	       __node != __first._M_node; --__node)
1138 	    __result = std::__copy_move_backward_a1<_IsMove>(
1139 		*__node, *__node + _Iter::_S_buffer_size(), __result);
1140 
1141 	  return std::__copy_move_backward_a1<_IsMove>(
1142 			__first._M_cur, __first._M_last, __result);
1143 	}
1144 
1145       return std::__copy_move_backward_a1<_IsMove>(
1146 		__first._M_cur, __last._M_cur, __result);
1147     }
1148 
1149   template<bool _IsMove,
1150 	   typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1151     _OI
1152     __copy_move_backward_a1(
1153 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1154 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1155 		_OI __result)
1156     { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
1157 
1158   template<bool _IsMove,
1159 	   typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
1160     _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1161     __copy_move_backward_a1(
1162 		_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1163 		_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1164 		_GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
1165     { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
1166 
1167   template<bool _IsMove, typename _II, typename _Tp>
1168     typename __gnu_cxx::__enable_if<
1169       __is_random_access_iter<_II>::__value,
1170       _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
1171     __copy_move_backward_a1(_II __first, _II __last,
1172 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1173     {
1174       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
1175       typedef typename _Iter::difference_type difference_type;
1176 
1177       difference_type __len = __last - __first;
1178       while (__len > 0)
1179 	{
1180 	  difference_type __rlen = __result._M_cur - __result._M_first;
1181 	  _Tp* __rend = __result._M_cur;
1182 	  if (!__rlen)
1183 	    {
1184 	      __rlen = _Iter::_S_buffer_size();
1185 	      __rend = *(__result._M_node - 1) + __rlen;
1186 	    }
1187 
1188 	  const difference_type __clen = std::min(__len, __rlen);
1189 	  std::__copy_move_backward_a1<_IsMove>(__last - __clen, __last, __rend);
1190 
1191 	  __last -= __clen;
1192 	  __result -= __clen;
1193 	  __len -= __clen;
1194 	}
1195 
1196       return __result;
1197     }
1198 
1199   template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
1200     bool
1201     __equal_dit(
1202 	const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __first1,
1203 	const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __last1,
1204 	_II __first2)
1205     {
1206       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1207       if (__first1._M_node != __last1._M_node)
1208 	{
1209 	  if (!std::__equal_aux1(__first1._M_cur, __first1._M_last, __first2))
1210 	    return false;
1211 
1212 	  __first2 += __first1._M_last - __first1._M_cur;
1213 	  for (typename _Iter::_Map_pointer __node = __first1._M_node + 1;
1214 	       __node != __last1._M_node;
1215 	       __first2 += _Iter::_S_buffer_size(), ++__node)
1216 	    if (!std::__equal_aux1(*__node, *__node + _Iter::_S_buffer_size(),
1217 				  __first2))
1218 	      return false;
1219 
1220 	  return std::__equal_aux1(__last1._M_first, __last1._M_cur, __first2);
1221 	}
1222 
1223       return std::__equal_aux1(__first1._M_cur, __last1._M_cur, __first2);
1224     }
1225 
1226   template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
1227     typename __gnu_cxx::__enable_if<
1228       __is_random_access_iter<_II>::__value, bool>::__type
1229     __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first1,
1230 		 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last1,
1231 		 _II __first2)
1232     { return std::__equal_dit(__first1, __last1, __first2); }
1233 
1234   template<typename _Tp1, typename _Ref1, typename _Ptr1,
1235 	   typename _Tp2, typename _Ref2, typename _Ptr2>
1236     bool
1237     __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1238 		 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1239 		 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2)
1240     { return std::__equal_dit(__first1, __last1, __first2); }
1241 
1242   template<typename _II, typename _Tp, typename _Ref, typename _Ptr>
1243     typename __gnu_cxx::__enable_if<
1244       __is_random_access_iter<_II>::__value, bool>::__type
1245     __equal_aux1(_II __first1, _II __last1,
1246 		_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first2)
1247     {
1248       typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1249       typedef typename _Iter::difference_type difference_type;
1250 
1251       difference_type __len = __last1 - __first1;
1252       while (__len > 0)
1253 	{
1254 	  const difference_type __clen
1255 	    = std::min(__len, __first2._M_last - __first2._M_cur);
1256 	  if (!std::__equal_aux1(__first1, __first1 + __clen, __first2._M_cur))
1257 	    return false;
1258 
1259 	  __first1 += __clen;
1260 	  __len -= __clen;
1261 	  __first2 += __clen;
1262 	}
1263 
1264       return true;
1265     }
1266 
1267   template<typename _Tp1, typename _Ref, typename _Ptr, typename _Tp2>
1268     int
1269     __lex_cmp_dit(
1270 	_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __first1,
1271 	_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __last1,
1272 	const _Tp2* __first2, const _Tp2* __last2)
1273     {
1274       const bool __simple =
1275 	(__is_memcmp_ordered_with<_Tp1, _Tp2>::__value
1276 	 && __is_pointer<_Ptr>::__value
1277 #if __cplusplus > 201703L && __cpp_lib_concepts
1278 	 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile
1279 	 // so __is_byte<T> could be true, but we can't use memcmp with
1280 	 // volatile data.
1281 	 && !is_volatile_v<_Tp1>
1282 	 && !is_volatile_v<_Tp2>
1283 #endif
1284 	 );
1285       typedef std::__lexicographical_compare<__simple> _Lc;
1286 
1287       while (__first1._M_node != __last1._M_node)
1288 	{
1289 	  const ptrdiff_t __len1 = __first1._M_last - __first1._M_cur;
1290 	  const ptrdiff_t __len2 = __last2 - __first2;
1291 	  const ptrdiff_t __len = std::min(__len1, __len2);
1292 	  // if __len1 > __len2 this will return a positive value:
1293 	  if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_last,
1294 				      __first2, __first2 + __len))
1295 	    return __ret;
1296 
1297 	  __first1 += __len;
1298 	  __first2 += __len;
1299 	}
1300       return _Lc::__3way(__first1._M_cur, __last1._M_cur,
1301 			 __first2, __last2);
1302     }
1303 
1304   template<typename _Tp1, typename _Ref1, typename _Ptr1,
1305 	   typename _Tp2>
1306     inline bool
1307     __lexicographical_compare_aux1(
1308 	_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1309 	_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1310 	_Tp2* __first2, _Tp2* __last2)
1311     { return std::__lex_cmp_dit(__first1, __last1, __first2, __last2) < 0; }
1312 
1313   template<typename _Tp1,
1314 	   typename _Tp2, typename _Ref2, typename _Ptr2>
1315     inline  bool
1316     __lexicographical_compare_aux1(_Tp1* __first1, _Tp1* __last1,
1317 	_GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2,
1318 	_GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2)
1319     { return std::__lex_cmp_dit(__first2, __last2, __first1, __last1) > 0; }
1320 
1321   template<typename _Tp1, typename _Ref1, typename _Ptr1,
1322 	   typename _Tp2, typename _Ref2, typename _Ptr2>
1323     inline bool
1324     __lexicographical_compare_aux1(
1325 		_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1326 		_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1327 		_GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2,
1328 		_GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2)
1329     {
1330       const bool __simple =
1331 	(__is_memcmp_ordered_with<_Tp1, _Tp2>::__value
1332 	 && __is_pointer<_Ptr1>::__value
1333 	 && __is_pointer<_Ptr2>::__value
1334 #if __cplusplus > 201703L && __cpp_lib_concepts
1335 	 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile
1336 	 // so __is_byte<T> could be true, but we can't use memcmp with
1337 	 // volatile data.
1338 	 && !is_volatile_v<_Tp1>
1339 	 && !is_volatile_v<_Tp2>
1340 #endif
1341 	 );
1342       typedef std::__lexicographical_compare<__simple> _Lc;
1343 
1344       while (__first1 != __last1)
1345 	{
1346 	  const ptrdiff_t __len2 = __first2._M_node == __last2._M_node
1347 	    ? __last2._M_cur - __first2._M_cur
1348 	    : __first2._M_last - __first2._M_cur;
1349 	  if (__len2 == 0)
1350 	    return false;
1351 	  const ptrdiff_t __len1 = __first1._M_node == __last1._M_node
1352 	    ? __last1._M_cur - __first1._M_cur
1353 	    : __first1._M_last - __first1._M_cur;
1354 	  const ptrdiff_t __len = std::min(__len1, __len2);
1355 	  if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_cur + __len,
1356 				      __first2._M_cur, __first2._M_cur + __len))
1357 	    return __ret < 0;
1358 
1359 	  __first1 += __len;
1360 	  __first2 += __len;
1361 	}
1362 
1363       return __last2 != __first2;
1364     }
1365 
1366 _GLIBCXX_END_NAMESPACE_VERSION
1367 } // namespace std
1368 
1369 #endif
1370