libstdc++
debug/deque
Go to the documentation of this file.
1 // Debugging deque implementation -*- C++ -*-
2 
3 // Copyright (C) 2003-2025 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 /** @file debug/deque
26  * This file is a GNU debug extension to the Standard C++ Library.
27  */
28 
29 #ifndef _GLIBCXX_DEBUG_DEQUE
30 #define _GLIBCXX_DEBUG_DEQUE 1
31 
32 #ifdef _GLIBCXX_SYSHDR
33 #pragma GCC system_header
34 #endif
35 
36 #include <bits/c++config.h>
37 namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
38  template<typename _Tp, typename _Allocator> class deque;
39 } } // namespace std::__debug
40 
41 #include <deque>
42 #include <debug/safe_sequence.h>
43 #include <debug/safe_container.h>
44 #include <debug/safe_iterator.h>
45 
46 namespace std _GLIBCXX_VISIBILITY(default)
47 {
48 namespace __debug
49 {
50  /// Class std::deque with safety/checking/debug instrumentation.
51  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
52  class deque
53  : public __gnu_debug::_Safe_container<
54  deque<_Tp, _Allocator>, _Allocator,
55  __gnu_debug::_Safe_sequence>,
56  public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
57  {
58  typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
59  typedef __gnu_debug::_Safe_container<
60  deque, _Allocator, __gnu_debug::_Safe_sequence> _Safe;
61 
62  typedef typename _Base::const_iterator _Base_const_iterator;
63  typedef typename _Base::iterator _Base_iterator;
64  typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
65 
66  template<typename _ItT, typename _SeqT, typename _CatT>
67  friend class ::__gnu_debug::_Safe_iterator;
68 
69  // Reference wrapper for base class. Disambiguates deque(const _Base&)
70  // from copy constructor by requiring a user-defined conversion.
71  // See PR libstdc++/90102.
72  struct _Base_ref
73  {
74  _Base_ref(const _Base& __r) : _M_ref(__r) { }
75 
76  const _Base& _M_ref;
77  };
78 
79  public:
80  typedef typename _Base::reference reference;
81  typedef typename _Base::const_reference const_reference;
82 
83  typedef __gnu_debug::_Safe_iterator<_Base_iterator, deque>
84  iterator;
85  typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque>
86  const_iterator;
87 
88  typedef typename _Base::size_type size_type;
89  typedef typename _Base::difference_type difference_type;
90 
91  typedef _Tp value_type;
92  typedef _Allocator allocator_type;
93  typedef typename _Base::pointer pointer;
94  typedef typename _Base::const_pointer const_pointer;
95  typedef std::reverse_iterator<iterator> reverse_iterator;
96  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
97 
98  // 23.2.1.1 construct/copy/destroy:
99 
100 #if __cplusplus < 201103L
101  deque()
102  : _Base() { }
103 
104  deque(const deque& __x)
105  : _Base(__x) { }
106 
107  ~deque() { }
108 #else
109  deque() = default;
110  deque(const deque&) = default;
111  deque(deque&&) = default;
112 
113  deque(const deque& __d, const __type_identity_t<_Allocator>& __a)
114  : _Base(__d, __a) { }
115 
116  deque(deque&& __d, const __type_identity_t<_Allocator>& __a)
117  : _Safe(std::move(__d)), _Base(std::move(__d), __a) { }
118 
119  deque(initializer_list<value_type> __l,
120  const allocator_type& __a = allocator_type())
121  : _Base(__l, __a) { }
122 
123  ~deque() = default;
124 #endif
125 
126  explicit
127  deque(const _Allocator& __a)
128  : _Base(__a) { }
129 
130 #if __cplusplus >= 201103L
131  explicit
132  deque(size_type __n, const _Allocator& __a = _Allocator())
133  : _Base(__n, __a) { }
134 
135  deque(size_type __n, const __type_identity_t<_Tp>& __value,
136  const _Allocator& __a = _Allocator())
137  : _Base(__n, __value, __a) { }
138 #else
139  explicit
140  deque(size_type __n, const _Tp& __value = _Tp(),
141  const _Allocator& __a = _Allocator())
142  : _Base(__n, __value, __a) { }
143 #endif
144 
145 #if __cplusplus >= 201103L
146  template<class _InputIterator,
147  typename = std::_RequireInputIter<_InputIterator>>
148 #else
149  template<class _InputIterator>
150 #endif
151  deque(_InputIterator __first, _InputIterator __last,
152  const _Allocator& __a = _Allocator())
153  : _Base(__gnu_debug::__base(
154  __glibcxx_check_valid_constructor_range(__first, __last)),
155  __gnu_debug::__base(__last), __a)
156  { }
157 
158 #if __glibcxx_containers_ranges // C++ >= 23
159  template<__detail::__container_compatible_range<_Tp> _Rg>
160  deque(from_range_t, _Rg&& __rg, const _Allocator& __a = _Allocator())
161  : _Base(from_range, std::forward<_Rg>(__rg), __a)
162  { }
163 #endif
164 
165  deque(_Base_ref __x)
166  : _Base(__x._M_ref) { }
167 
168 #if __cplusplus >= 201103L
169  deque&
170  operator=(const deque&) = default;
171 
172  deque&
173  operator=(deque&&) = default;
174 
175  deque&
176  operator=(initializer_list<value_type> __l)
177  {
178  _Base::operator=(__l);
179  this->_M_invalidate_all();
180  return *this;
181  }
182 #endif
183 
184 #if __cplusplus >= 201103L
185  template<class _InputIterator,
186  typename = std::_RequireInputIter<_InputIterator>>
187 #else
188  template<class _InputIterator>
189 #endif
190  void
191  assign(_InputIterator __first, _InputIterator __last)
192  {
193  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
194  __glibcxx_check_valid_range2(__first, __last, __dist);
195  if (__dist.second >= __gnu_debug::__dp_sign)
196  _Base::assign(__gnu_debug::__unsafe(__first),
197  __gnu_debug::__unsafe(__last));
198  else
199  _Base::assign(__first, __last);
200 
201  this->_M_invalidate_all();
202  }
203 
204  void
205  assign(size_type __n, const _Tp& __t)
206  {
207  _Base::assign(__n, __t);
208  this->_M_invalidate_all();
209  }
210 
211 #if __cplusplus >= 201103L
212  void
213  assign(initializer_list<value_type> __l)
214  {
215  _Base::assign(__l);
216  this->_M_invalidate_all();
217  }
218 #endif
219 
220 #if __glibcxx_containers_ranges // C++ >= 23
221  template<std::__detail::__container_compatible_range<_Tp> _Rg>
222  void
223  assign_range(_Rg&& __rg)
224  {
225  _Base::assign_range(std::forward<_Rg>(__rg));
226  this->_M_invalidate_all();
227  }
228 #endif
229 
230  using _Base::get_allocator;
231 
232  // iterators:
233  _GLIBCXX_NODISCARD
234  iterator
235  begin() _GLIBCXX_NOEXCEPT
236  { return iterator(_Base::begin(), this); }
237 
238  _GLIBCXX_NODISCARD
239  const_iterator
240  begin() const _GLIBCXX_NOEXCEPT
241  { return const_iterator(_Base::begin(), this); }
242 
243  _GLIBCXX_NODISCARD
244  iterator
245  end() _GLIBCXX_NOEXCEPT
246  { return iterator(_Base::end(), this); }
247 
248  _GLIBCXX_NODISCARD
249  const_iterator
250  end() const _GLIBCXX_NOEXCEPT
251  { return const_iterator(_Base::end(), this); }
252 
253  _GLIBCXX_NODISCARD
254  reverse_iterator
255  rbegin() _GLIBCXX_NOEXCEPT
256  { return reverse_iterator(end()); }
257 
258  _GLIBCXX_NODISCARD
259  const_reverse_iterator
260  rbegin() const _GLIBCXX_NOEXCEPT
261  { return const_reverse_iterator(end()); }
262 
263  _GLIBCXX_NODISCARD
264  reverse_iterator
265  rend() _GLIBCXX_NOEXCEPT
266  { return reverse_iterator(begin()); }
267 
268  _GLIBCXX_NODISCARD
269  const_reverse_iterator
270  rend() const _GLIBCXX_NOEXCEPT
271  { return const_reverse_iterator(begin()); }
272 
273 #if __cplusplus >= 201103L
274  [[__nodiscard__]]
275  const_iterator
276  cbegin() const noexcept
277  { return const_iterator(_Base::begin(), this); }
278 
279  [[__nodiscard__]]
280  const_iterator
281  cend() const noexcept
282  { return const_iterator(_Base::end(), this); }
283 
284  [[__nodiscard__]]
285  const_reverse_iterator
286  crbegin() const noexcept
287  { return const_reverse_iterator(end()); }
288 
289  [[__nodiscard__]]
290  const_reverse_iterator
291  crend() const noexcept
292  { return const_reverse_iterator(begin()); }
293 #endif
294 
295  private:
296  void
297  _M_invalidate_after_nth(difference_type __n)
298  {
299  typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
300  this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
301  }
302 
303  public:
304  // 23.2.1.2 capacity:
305  using _Base::size;
306  using _Base::max_size;
307 
308 #if __cplusplus >= 201103L
309  void
310  resize(size_type __sz)
311  {
312  bool __invalidate_all = __sz > this->size();
313  if (__sz < this->size())
314  this->_M_invalidate_after_nth(__sz);
315 
316  _Base::resize(__sz);
317 
318  if (__invalidate_all)
319  this->_M_invalidate_all();
320  }
321 
322  void
323  resize(size_type __sz, const _Tp& __c)
324  {
325  bool __invalidate_all = __sz > this->size();
326  if (__sz < this->size())
327  this->_M_invalidate_after_nth(__sz);
328 
329  _Base::resize(__sz, __c);
330 
331  if (__invalidate_all)
332  this->_M_invalidate_all();
333  }
334 #else
335  void
336  resize(size_type __sz, _Tp __c = _Tp())
337  {
338  bool __invalidate_all = __sz > this->size();
339  if (__sz < this->size())
340  this->_M_invalidate_after_nth(__sz);
341 
342  _Base::resize(__sz, __c);
343 
344  if (__invalidate_all)
345  this->_M_invalidate_all();
346  }
347 #endif
348 
349 #if __cplusplus >= 201103L
350  void
351  shrink_to_fit() noexcept
352  {
353  if (_Base::_M_shrink_to_fit())
354  this->_M_invalidate_all();
355  }
356 #endif
357 
358  using _Base::empty;
359 
360  // element access:
361  _GLIBCXX_NODISCARD
362  reference
363  operator[](size_type __n) _GLIBCXX_NOEXCEPT
364  {
365  __glibcxx_check_subscript(__n);
366  return _Base::operator[](__n);
367  }
368 
369  _GLIBCXX_NODISCARD
370  const_reference
371  operator[](size_type __n) const _GLIBCXX_NOEXCEPT
372  {
373  __glibcxx_check_subscript(__n);
374  return _Base::operator[](__n);
375  }
376 
377  using _Base::at;
378 
379  _GLIBCXX_NODISCARD
380  reference
381  front() _GLIBCXX_NOEXCEPT
382  {
383  __glibcxx_check_nonempty();
384  return _Base::front();
385  }
386 
387  _GLIBCXX_NODISCARD
388  const_reference
389  front() const _GLIBCXX_NOEXCEPT
390  {
391  __glibcxx_check_nonempty();
392  return _Base::front();
393  }
394 
395  _GLIBCXX_NODISCARD
396  reference
397  back() _GLIBCXX_NOEXCEPT
398  {
399  __glibcxx_check_nonempty();
400  return _Base::back();
401  }
402 
403  _GLIBCXX_NODISCARD
404  const_reference
405  back() const _GLIBCXX_NOEXCEPT
406  {
407  __glibcxx_check_nonempty();
408  return _Base::back();
409  }
410 
411  // 23.2.1.3 modifiers:
412  void
413  push_front(const _Tp& __x)
414  {
415  _Base::push_front(__x);
416  this->_M_invalidate_all();
417  }
418 
419  void
420  push_back(const _Tp& __x)
421  {
422  _Base::push_back(__x);
423  this->_M_invalidate_all();
424  }
425 
426 #if __cplusplus >= 201103L
427  void
428  push_front(_Tp&& __x)
429  { emplace_front(std::move(__x)); }
430 
431  void
432  push_back(_Tp&& __x)
433  { emplace_back(std::move(__x)); }
434 
435  template<typename... _Args>
436 #if __cplusplus > 201402L
437  reference
438 #else
439  void
440 #endif
441  emplace_front(_Args&&... __args)
442  {
443  _Base::emplace_front(std::forward<_Args>(__args)...);
444  this->_M_invalidate_all();
445 #if __cplusplus > 201402L
446  return front();
447 #endif
448  }
449 
450  template<typename... _Args>
451 #if __cplusplus > 201402L
452  reference
453 #else
454  void
455 #endif
456  emplace_back(_Args&&... __args)
457  {
458  _Base::emplace_back(std::forward<_Args>(__args)...);
459  this->_M_invalidate_all();
460 #if __cplusplus > 201402L
461  return back();
462 #endif
463  }
464 
465  template<typename... _Args>
466  iterator
467  emplace(const_iterator __position, _Args&&... __args)
468  {
469  __glibcxx_check_insert(__position);
470  _Base_iterator __res = _Base::emplace(__position.base(),
471  std::forward<_Args>(__args)...);
472  this->_M_invalidate_all();
473  return iterator(__res, this);
474  }
475 #endif
476 
477  iterator
478 #if __cplusplus >= 201103L
479  insert(const_iterator __position, const _Tp& __x)
480 #else
481  insert(iterator __position, const _Tp& __x)
482 #endif
483  {
484  __glibcxx_check_insert(__position);
485  _Base_iterator __res = _Base::insert(__position.base(), __x);
486  this->_M_invalidate_all();
487  return iterator(__res, this);
488  }
489 
490 #if __cplusplus >= 201103L
491  iterator
492  insert(const_iterator __position, _Tp&& __x)
493  { return emplace(__position, std::move(__x)); }
494 
495  iterator
496  insert(const_iterator __position, initializer_list<value_type> __l)
497  {
498  __glibcxx_check_insert(__position);
499  _Base_iterator __res = _Base::insert(__position.base(), __l);
500  this->_M_invalidate_all();
501  return iterator(__res, this);
502  }
503 #endif
504 
505 #if __cplusplus >= 201103L
506  iterator
507  insert(const_iterator __position, size_type __n, const _Tp& __x)
508  {
509  __glibcxx_check_insert(__position);
510  _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
511  this->_M_invalidate_all();
512  return iterator(__res, this);
513  }
514 #else
515  void
516  insert(iterator __position, size_type __n, const _Tp& __x)
517  {
518  __glibcxx_check_insert(__position);
519  _Base::insert(__position.base(), __n, __x);
520  this->_M_invalidate_all();
521  }
522 #endif
523 
524 #if __cplusplus >= 201103L
525  template<class _InputIterator,
526  typename = std::_RequireInputIter<_InputIterator>>
527  iterator
528  insert(const_iterator __position,
529  _InputIterator __first, _InputIterator __last)
530  {
531  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
532  __glibcxx_check_insert_range(__position, __first, __last, __dist);
533  _Base_iterator __res;
534  if (__dist.second >= __gnu_debug::__dp_sign)
535  __res = _Base::insert(__position.base(),
536  __gnu_debug::__unsafe(__first),
537  __gnu_debug::__unsafe(__last));
538  else
539  __res = _Base::insert(__position.base(), __first, __last);
540 
541  this->_M_invalidate_all();
542  return iterator(__res, this);
543  }
544 #else
545  template<class _InputIterator>
546  void
547  insert(iterator __position,
548  _InputIterator __first, _InputIterator __last)
549  {
550  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
551  __glibcxx_check_insert_range(__position, __first, __last, __dist);
552 
553  if (__dist.second >= __gnu_debug::__dp_sign)
554  _Base::insert(__position.base(),
555  __gnu_debug::__unsafe(__first),
556  __gnu_debug::__unsafe(__last));
557  else
558  _Base::insert(__position.base(), __first, __last);
559 
560  this->_M_invalidate_all();
561  }
562 #endif
563 
564 #if __glibcxx_containers_ranges // C++ >= 23
565  template<__detail::__container_compatible_range<_Tp> _Rg>
566  iterator
567  insert_range(const_iterator __pos, _Rg&& __rg)
568  {
569  auto __res = _Base::insert_range(__pos.base(), std::forward<_Rg>(__rg));
570  this->_M_invalidate_all();
571  return iterator(__res, this);
572  }
573 
574  template<std::__detail::__container_compatible_range<_Tp> _Rg>
575  void
576  prepend_range(_Rg&& __rg)
577  {
578  _Base::prepend_range(std::forward<_Rg>(__rg));
579  this->_M_invalidate_all();
580  }
581 
582  template<std::__detail::__container_compatible_range<_Tp> _Rg>
583  void
584  append_range(_Rg&& __rg)
585  {
586  _Base::append_range(std::forward<_Rg>(__rg));
587  this->_M_invalidate_all();
588  }
589 #endif
590 
591  void
592  pop_front() _GLIBCXX_NOEXCEPT
593  {
594  __glibcxx_check_nonempty();
595  this->_M_invalidate_if(_Equal(_Base::begin()));
596  _Base::pop_front();
597  }
598 
599  void
600  pop_back() _GLIBCXX_NOEXCEPT
601  {
602  __glibcxx_check_nonempty();
603  this->_M_invalidate_if(_Equal(--_Base::end()));
604  _Base::pop_back();
605  }
606 
607  iterator
608 #if __cplusplus >= 201103L
609  erase(const_iterator __position)
610 #else
611  erase(iterator __position)
612 #endif
613  {
614  __glibcxx_check_erase(__position);
615 #if __cplusplus >= 201103L
616  _Base_const_iterator __victim = __position.base();
617 #else
618  _Base_iterator __victim = __position.base();
619 #endif
620  if (__victim == _Base::begin() || __victim == _Base::end() - 1)
621  {
622  this->_M_invalidate_if(_Equal(__victim));
623  return iterator(_Base::erase(__victim), this);
624  }
625  else
626  {
627  _Base_iterator __res = _Base::erase(__victim);
628  this->_M_invalidate_all();
629  return iterator(__res, this);
630  }
631  }
632 
633  iterator
634 #if __cplusplus >= 201103L
635  erase(const_iterator __first, const_iterator __last)
636 #else
637  erase(iterator __first, iterator __last)
638 #endif
639  {
640  // _GLIBCXX_RESOLVE_LIB_DEFECTS
641  // 151. can't currently clear() empty container
642  __glibcxx_check_erase_range(__first, __last);
643 
644  if (__first.base() == __last.base())
645 #if __cplusplus >= 201103L
646  return iterator(__first.base()._M_const_cast(), this);
647 #else
648  return __first;
649 #endif
650  else if (__first.base() == _Base::begin()
651  || __last.base() == _Base::end())
652  {
653  this->_M_detach_singular();
654  for (_Base_const_iterator __position = __first.base();
655  __position != __last.base(); ++__position)
656  {
657  this->_M_invalidate_if(_Equal(__position));
658  }
659  __try
660  {
661  return iterator(_Base::erase(__first.base(), __last.base()),
662  this);
663  }
664  __catch(...)
665  {
666  this->_M_revalidate_singular();
667  __throw_exception_again;
668  }
669  }
670  else
671  {
672  _Base_iterator __res = _Base::erase(__first.base(),
673  __last.base());
674  this->_M_invalidate_all();
675  return iterator(__res, this);
676  }
677  }
678 
679  void
680  swap(deque& __x)
681  _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
682  {
683  _Safe::_M_swap(__x);
684  _Base::swap(__x);
685  }
686 
687  void
688  clear() _GLIBCXX_NOEXCEPT
689  {
690  _Base::clear();
691  this->_M_invalidate_all();
692  }
693 
694  _Base&
695  _M_base() _GLIBCXX_NOEXCEPT { return *this; }
696 
697  const _Base&
698  _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
699  };
700 
701 #if __cpp_deduction_guides >= 201606
702  template<typename _InputIterator, typename _ValT
703  = typename iterator_traits<_InputIterator>::value_type,
704  typename _Allocator = allocator<_ValT>,
705  typename = _RequireInputIter<_InputIterator>,
706  typename = _RequireAllocator<_Allocator>>
707  deque(_InputIterator, _InputIterator, _Allocator = _Allocator())
708  -> deque<_ValT, _Allocator>;
709 
710  template<typename _Tp, typename _Allocator = allocator<_Tp>,
711  typename = _RequireAllocator<_Allocator>>
712  deque(size_t, _Tp, _Allocator = _Allocator())
713  -> deque<_Tp, _Allocator>;
714 
715 #if __glibcxx_containers_ranges // C++ >= 23
716  template<ranges::input_range _Rg,
717  typename _Alloc = allocator<ranges::range_value_t<_Rg>>>
718  deque(from_range_t, _Rg&&, _Alloc = _Alloc())
719  -> deque<ranges::range_value_t<_Rg>, _Alloc>;
720 #endif
721 #endif
722 
723  template<typename _Tp, typename _Alloc>
724  inline bool
725  operator==(const deque<_Tp, _Alloc>& __lhs,
726  const deque<_Tp, _Alloc>& __rhs)
727  { return __lhs._M_base() == __rhs._M_base(); }
728 
729 #if __cpp_lib_three_way_comparison
730  template<typename _Tp, typename _Alloc>
731  constexpr __detail::__synth3way_t<_Tp>
732  operator<=>(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y)
733  { return __x._M_base() <=> __y._M_base(); }
734 #else
735  template<typename _Tp, typename _Alloc>
736  inline bool
737  operator!=(const deque<_Tp, _Alloc>& __lhs,
738  const deque<_Tp, _Alloc>& __rhs)
739  { return __lhs._M_base() != __rhs._M_base(); }
740 
741  template<typename _Tp, typename _Alloc>
742  inline bool
743  operator<(const deque<_Tp, _Alloc>& __lhs,
744  const deque<_Tp, _Alloc>& __rhs)
745  { return __lhs._M_base() < __rhs._M_base(); }
746 
747  template<typename _Tp, typename _Alloc>
748  inline bool
749  operator<=(const deque<_Tp, _Alloc>& __lhs,
750  const deque<_Tp, _Alloc>& __rhs)
751  { return __lhs._M_base() <= __rhs._M_base(); }
752 
753  template<typename _Tp, typename _Alloc>
754  inline bool
755  operator>=(const deque<_Tp, _Alloc>& __lhs,
756  const deque<_Tp, _Alloc>& __rhs)
757  { return __lhs._M_base() >= __rhs._M_base(); }
758 
759  template<typename _Tp, typename _Alloc>
760  inline bool
761  operator>(const deque<_Tp, _Alloc>& __lhs,
762  const deque<_Tp, _Alloc>& __rhs)
763  { return __lhs._M_base() > __rhs._M_base(); }
764 #endif // three-way comparison
765 
766  template<typename _Tp, typename _Alloc>
767  inline void
768  swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
769  _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
770  { __lhs.swap(__rhs); }
771 
772 } // namespace __debug
773 } // namespace std
774 
775 #endif