1 // Queue implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2021 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) 1996,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/stl_queue.h
52  *  This is an internal header file, included by other library headers.
53  *  Do not attempt to use it directly. @headername{queue}
54  */
55 
56 #ifndef _STL_QUEUE_H
57 #define _STL_QUEUE_H 1
58 
59 #include <bits/concept_check.h>
60 #include <debug/debug.h>
61 #if __cplusplus >= 201103L
62 # include <bits/uses_allocator.h>
63 #endif
64 
_GLIBCXX_VISIBILITY(default)65 namespace std _GLIBCXX_VISIBILITY(default)
66 {
67 _GLIBCXX_BEGIN_NAMESPACE_VERSION
68 
69   /**
70    *  @brief  A standard container giving FIFO behavior.
71    *
72    *  @ingroup sequences
73    *
74    *  @tparam _Tp  Type of element.
75    *  @tparam _Sequence  Type of underlying sequence, defaults to deque<_Tp>.
76    *
77    *  Meets many of the requirements of a
78    *  <a href="tables.html#65">container</a>,
79    *  but does not define anything to do with iterators.  Very few of the
80    *  other standard container interfaces are defined.
81    *
82    *  This is not a true container, but an @e adaptor.  It holds another
83    *  container, and provides a wrapper interface to that container.  The
84    *  wrapper is what enforces strict first-in-first-out %queue behavior.
85    *
86    *  The second template parameter defines the type of the underlying
87    *  sequence/container.  It defaults to std::deque, but it can be any type
88    *  that supports @c front, @c back, @c push_back, and @c pop_front,
89    *  such as std::list or an appropriate user-defined type.
90    *
91    *  Members not found in @a normal containers are @c container_type,
92    *  which is a typedef for the second Sequence parameter, and @c push and
93    *  @c pop, which are standard %queue/FIFO operations.
94   */
95   template<typename _Tp, typename _Sequence = deque<_Tp> >
96     class queue
97     {
98 #ifdef _GLIBCXX_CONCEPT_CHECKS
99       // concept requirements
100       typedef typename _Sequence::value_type _Sequence_value_type;
101 # if __cplusplus < 201103L
102       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
103 # endif
104       __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
105       __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
106       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
107 #endif
108 
109       template<typename _Tp1, typename _Seq1>
110 	friend bool
111 	operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
112 
113       template<typename _Tp1, typename _Seq1>
114 	friend bool
115 	operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
116 
117 #if __cpp_lib_three_way_comparison
118       template<typename _Tp1, three_way_comparable _Seq1>
119 	friend compare_three_way_result_t<_Seq1>
120 	operator<=>(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
121 #endif
122 
123 #if __cplusplus >= 201103L
124       template<typename _Alloc>
125 	using _Uses = typename
126 	  enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
127 
128 #if __cplusplus >= 201703L
129       // _GLIBCXX_RESOLVE_LIB_DEFECTS
130       // 2566. Requirements on the first template parameter of container
131       // adaptors
132       static_assert(is_same<_Tp, typename _Sequence::value_type>::value,
133 	  "value_type must be the same as the underlying container");
134 #endif // C++17
135 #endif // C++11
136 
137     public:
138       typedef typename	_Sequence::value_type		value_type;
139       typedef typename	_Sequence::reference		reference;
140       typedef typename	_Sequence::const_reference	const_reference;
141       typedef typename	_Sequence::size_type		size_type;
142       typedef		_Sequence			container_type;
143 
144     protected:
145       /*  Maintainers wondering why this isn't uglified as per style
146        *  guidelines should note that this name is specified in the standard,
147        *  C++98 [23.2.3.1].
148        *  (Why? Presumably for the same reason that it's protected instead
149        *  of private: to allow derivation.  But none of the other
150        *  containers allow for derivation.  Odd.)
151        */
152        ///  @c c is the underlying container.
153       _Sequence c;
154 
155     public:
156       /**
157        *  @brief  Default constructor creates no elements.
158        */
159 #if __cplusplus < 201103L
160       explicit
161       queue(const _Sequence& __c = _Sequence())
162       : c(__c) { }
163 #else
164       template<typename _Seq = _Sequence, typename _Requires = typename
165 	       enable_if<is_default_constructible<_Seq>::value>::type>
166 	queue()
167 	: c() { }
168 
169       explicit
170       queue(const _Sequence& __c)
171       : c(__c) { }
172 
173       explicit
174       queue(_Sequence&& __c)
175       : c(std::move(__c)) { }
176 
177       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
178 	explicit
179 	queue(const _Alloc& __a)
180 	: c(__a) { }
181 
182       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
183 	queue(const _Sequence& __c, const _Alloc& __a)
184 	: c(__c, __a) { }
185 
186       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
187 	queue(_Sequence&& __c, const _Alloc& __a)
188 	: c(std::move(__c), __a) { }
189 
190       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
191 	queue(const queue& __q, const _Alloc& __a)
192 	: c(__q.c, __a) { }
193 
194       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
195 	queue(queue&& __q, const _Alloc& __a)
196 	: c(std::move(__q.c), __a) { }
197 
198 #if __cplusplus > 202002L
199 #define __cpp_lib_adaptor_iterator_pair_constructor 202106L
200 
201       template<typename _InputIterator,
202 	       typename = _RequireInputIter<_InputIterator>>
203 	queue(_InputIterator __first, _InputIterator __last)
204 	: c(__first, __last) { }
205 
206       template<typename _InputIterator, typename _Alloc,
207 	       typename = _RequireInputIter<_InputIterator>,
208 	       typename = _Uses<_Alloc>>
209 	queue(_InputIterator __first, _InputIterator __last, const _Alloc& __a)
210 	: c(__first, __last, __a) { }
211 #endif
212 #endif
213 
214       /**
215        *  Returns true if the %queue is empty.
216        */
217       _GLIBCXX_NODISCARD bool
218       empty() const
219       { return c.empty(); }
220 
221       /**  Returns the number of elements in the %queue.  */
222       _GLIBCXX_NODISCARD
223       size_type
224       size() const
225       { return c.size(); }
226 
227       /**
228        *  Returns a read/write reference to the data at the first
229        *  element of the %queue.
230        */
231       _GLIBCXX_NODISCARD
232       reference
233       front()
234       {
235 	__glibcxx_requires_nonempty();
236 	return c.front();
237       }
238 
239       /**
240        *  Returns a read-only (constant) reference to the data at the first
241        *  element of the %queue.
242        */
243       _GLIBCXX_NODISCARD
244       const_reference
245       front() const
246       {
247 	__glibcxx_requires_nonempty();
248 	return c.front();
249       }
250 
251       /**
252        *  Returns a read/write reference to the data at the last
253        *  element of the %queue.
254        */
255       _GLIBCXX_NODISCARD
256       reference
257       back()
258       {
259 	__glibcxx_requires_nonempty();
260 	return c.back();
261       }
262 
263       /**
264        *  Returns a read-only (constant) reference to the data at the last
265        *  element of the %queue.
266        */
267       _GLIBCXX_NODISCARD
268       const_reference
269       back() const
270       {
271 	__glibcxx_requires_nonempty();
272 	return c.back();
273       }
274 
275       /**
276        *  @brief  Add data to the end of the %queue.
277        *  @param  __x  Data to be added.
278        *
279        *  This is a typical %queue operation.  The function creates an
280        *  element at the end of the %queue and assigns the given data
281        *  to it.  The time complexity of the operation depends on the
282        *  underlying sequence.
283        */
284       void
285       push(const value_type& __x)
286       { c.push_back(__x); }
287 
288 #if __cplusplus >= 201103L
289       void
290       push(value_type&& __x)
291       { c.push_back(std::move(__x)); }
292 
293 #if __cplusplus > 201402L
294       template<typename... _Args>
295 	decltype(auto)
296 	emplace(_Args&&... __args)
297 	{ return c.emplace_back(std::forward<_Args>(__args)...); }
298 #else
299       template<typename... _Args>
300 	void
301 	emplace(_Args&&... __args)
302 	{ c.emplace_back(std::forward<_Args>(__args)...); }
303 #endif
304 #endif
305 
306       /**
307        *  @brief  Removes first element.
308        *
309        *  This is a typical %queue operation.  It shrinks the %queue by one.
310        *  The time complexity of the operation depends on the underlying
311        *  sequence.
312        *
313        *  Note that no data is returned, and if the first element's
314        *  data is needed, it should be retrieved before pop() is
315        *  called.
316        */
317       void
318       pop()
319       {
320 	__glibcxx_requires_nonempty();
321 	c.pop_front();
322       }
323 
324 #if __cplusplus >= 201103L
325       void
326       swap(queue& __q)
327 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
328       noexcept(__is_nothrow_swappable<_Sequence>::value)
329 #else
330       noexcept(__is_nothrow_swappable<_Tp>::value)
331 #endif
332       {
333 	using std::swap;
334 	swap(c, __q.c);
335       }
336 #endif // __cplusplus >= 201103L
337     };
338 
339 #if __cpp_deduction_guides >= 201606
340   template<typename _Container,
341 	   typename = _RequireNotAllocator<_Container>>
342     queue(_Container) -> queue<typename _Container::value_type, _Container>;
343 
344   template<typename _Container, typename _Allocator,
345 	   typename = _RequireNotAllocator<_Container>>
346     queue(_Container, _Allocator)
347     -> queue<typename _Container::value_type, _Container>;
348 
349 #ifdef __cpp_lib_adaptor_iterator_pair_constructor
350   template<typename _InputIterator,
351 	   typename _ValT
352 	     = typename iterator_traits<_InputIterator>::value_type,
353 	   typename = _RequireInputIter<_InputIterator>>
354     queue(_InputIterator, _InputIterator) -> queue<_ValT>;
355 
356   template<typename _InputIterator, typename _Allocator,
357 	   typename _ValT
358 	     = typename iterator_traits<_InputIterator>::value_type,
359 	   typename = _RequireInputIter<_InputIterator>,
360 	   typename = _RequireAllocator<_Allocator>>
361     queue(_InputIterator, _InputIterator, _Allocator)
362     -> queue<_ValT, deque<_ValT, _Allocator>>;
363 #endif
364 #endif
365 
366   /**
367    *  @brief  Queue equality comparison.
368    *  @param  __x  A %queue.
369    *  @param  __y  A %queue of the same type as @a __x.
370    *  @return  True iff the size and elements of the queues are equal.
371    *
372    *  This is an equivalence relation.  Complexity and semantics depend on the
373    *  underlying sequence type, but the expected rules are:  this relation is
374    *  linear in the size of the sequences, and queues are considered equivalent
375    *  if their sequences compare equal.
376   */
377   template<typename _Tp, typename _Seq>
378     _GLIBCXX_NODISCARD
379     inline bool
380     operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
381     { return __x.c == __y.c; }
382 
383   /**
384    *  @brief  Queue ordering relation.
385    *  @param  __x  A %queue.
386    *  @param  __y  A %queue of the same type as @a x.
387    *  @return  True iff @a __x is lexicographically less than @a __y.
388    *
389    *  This is an total ordering relation.  Complexity and semantics
390    *  depend on the underlying sequence type, but the expected rules
391    *  are: this relation is linear in the size of the sequences, the
392    *  elements must be comparable with @c <, and
393    *  std::lexicographical_compare() is usually used to make the
394    *  determination.
395   */
396   template<typename _Tp, typename _Seq>
397     _GLIBCXX_NODISCARD
398     inline bool
399     operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
400     { return __x.c < __y.c; }
401 
402   /// Based on operator==
403   template<typename _Tp, typename _Seq>
404     _GLIBCXX_NODISCARD
405     inline bool
406     operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
407     { return !(__x == __y); }
408 
409   /// Based on operator<
410   template<typename _Tp, typename _Seq>
411     _GLIBCXX_NODISCARD
412     inline bool
413     operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
414     { return __y < __x; }
415 
416   /// Based on operator<
417   template<typename _Tp, typename _Seq>
418     _GLIBCXX_NODISCARD
419     inline bool
420     operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
421     { return !(__y < __x); }
422 
423   /// Based on operator<
424   template<typename _Tp, typename _Seq>
425     _GLIBCXX_NODISCARD
426     inline bool
427     operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
428     { return !(__x < __y); }
429 
430 #if __cpp_lib_three_way_comparison
431   template<typename _Tp, three_way_comparable _Seq>
432     [[nodiscard]]
433     inline compare_three_way_result_t<_Seq>
434     operator<=>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
435     { return __x.c <=> __y.c; }
436 #endif
437 
438 #if __cplusplus >= 201103L
439   template<typename _Tp, typename _Seq>
440     inline
441 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
442     // Constrained free swap overload, see p0185r1
443     typename enable_if<__is_swappable<_Seq>::value>::type
444 #else
445     void
446 #endif
447     swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
448     noexcept(noexcept(__x.swap(__y)))
449     { __x.swap(__y); }
450 
451   template<typename _Tp, typename _Seq, typename _Alloc>
452     struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
453     : public uses_allocator<_Seq, _Alloc>::type { };
454 #endif // __cplusplus >= 201103L
455 
456   /**
457    *  @brief  A standard container automatically sorting its contents.
458    *
459    *  @ingroup sequences
460    *
461    *  @tparam _Tp  Type of element.
462    *  @tparam _Sequence  Type of underlying sequence, defaults to vector<_Tp>.
463    *  @tparam _Compare  Comparison function object type, defaults to
464    *                    less<_Sequence::value_type>.
465    *
466    *  This is not a true container, but an @e adaptor.  It holds
467    *  another container, and provides a wrapper interface to that
468    *  container.  The wrapper is what enforces priority-based sorting
469    *  and %queue behavior.  Very few of the standard container/sequence
470    *  interface requirements are met (e.g., iterators).
471    *
472    *  The second template parameter defines the type of the underlying
473    *  sequence/container.  It defaults to std::vector, but it can be
474    *  any type that supports @c front(), @c push_back, @c pop_back,
475    *  and random-access iterators, such as std::deque or an
476    *  appropriate user-defined type.
477    *
478    *  The third template parameter supplies the means of making
479    *  priority comparisons.  It defaults to @c less<value_type> but
480    *  can be anything defining a strict weak ordering.
481    *
482    *  Members not found in @a normal containers are @c container_type,
483    *  which is a typedef for the second Sequence parameter, and @c
484    *  push, @c pop, and @c top, which are standard %queue operations.
485    *
486    *  @note No equality/comparison operators are provided for
487    *  %priority_queue.
488    *
489    *  @note Sorting of the elements takes place as they are added to,
490    *  and removed from, the %priority_queue using the
491    *  %priority_queue's member functions.  If you access the elements
492    *  by other means, and change their data such that the sorting
493    *  order would be different, the %priority_queue will not re-sort
494    *  the elements for you.  (How could it know to do so?)
495   */
496   template<typename _Tp, typename _Sequence = vector<_Tp>,
497 	   typename _Compare  = less<typename _Sequence::value_type> >
498     class priority_queue
499     {
500 #ifdef _GLIBCXX_CONCEPT_CHECKS
501       // concept requirements
502       typedef typename _Sequence::value_type _Sequence_value_type;
503 # if __cplusplus < 201103L
504       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
505 # endif
506       __glibcxx_class_requires(_Sequence, _SequenceConcept)
507       __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
508       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
509       __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
510 				_BinaryFunctionConcept)
511 #endif
512 
513 #if __cplusplus >= 201103L
514       template<typename _Alloc>
515 	using _Uses = typename
516 	  enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
517 
518 #if __cplusplus >= 201703L
519       // _GLIBCXX_RESOLVE_LIB_DEFECTS
520       // 2566. Requirements on the first template parameter of container
521       // adaptors
522       static_assert(is_same<_Tp, typename _Sequence::value_type>::value,
523 	  "value_type must be the same as the underlying container");
524 #endif // C++17
525 #endif // C++11
526 
527     public:
528       typedef typename	_Sequence::value_type		value_type;
529       typedef typename	_Sequence::reference		reference;
530       typedef typename	_Sequence::const_reference	const_reference;
531       typedef typename	_Sequence::size_type		size_type;
532       typedef		_Sequence			container_type;
533       // _GLIBCXX_RESOLVE_LIB_DEFECTS
534       // DR 2684. priority_queue lacking comparator typedef
535       typedef	       _Compare				value_compare;
536 
537     protected:
538       //  See queue::c for notes on these names.
539       _Sequence  c;
540       _Compare   comp;
541 
542     public:
543       /**
544        *  @brief  Default constructor creates no elements.
545        */
546 #if __cplusplus < 201103L
547       explicit
548       priority_queue(const _Compare& __x = _Compare(),
549 		     const _Sequence& __s = _Sequence())
550       : c(__s), comp(__x)
551       { std::make_heap(c.begin(), c.end(), comp); }
552 #else
553       template<typename _Seq = _Sequence, typename _Requires = typename
554 	       enable_if<__and_<is_default_constructible<_Compare>,
555 				is_default_constructible<_Seq>>::value>::type>
556 	priority_queue()
557 	: c(), comp() { }
558 
559       explicit
560       priority_queue(const _Compare& __x, const _Sequence& __s)
561       : c(__s), comp(__x)
562       { std::make_heap(c.begin(), c.end(), comp); }
563 
564       explicit
565       priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence())
566       : c(std::move(__s)), comp(__x)
567       { std::make_heap(c.begin(), c.end(), comp); }
568 
569       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
570 	explicit
571 	priority_queue(const _Alloc& __a)
572 	: c(__a), comp() { }
573 
574       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
575 	priority_queue(const _Compare& __x, const _Alloc& __a)
576 	: c(__a), comp(__x) { }
577 
578       // _GLIBCXX_RESOLVE_LIB_DEFECTS
579       // 2537. Constructors [...] taking allocators should call make_heap
580       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
581 	priority_queue(const _Compare& __x, const _Sequence& __c,
582 		       const _Alloc& __a)
583 	: c(__c, __a), comp(__x)
584 	{ std::make_heap(c.begin(), c.end(), comp); }
585 
586       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
587 	priority_queue(const _Compare& __x, _Sequence&& __c, const _Alloc& __a)
588 	: c(std::move(__c), __a), comp(__x)
589 	{ std::make_heap(c.begin(), c.end(), comp); }
590 
591       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
592 	priority_queue(const priority_queue& __q, const _Alloc& __a)
593 	: c(__q.c, __a), comp(__q.comp) { }
594 
595       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
596 	priority_queue(priority_queue&& __q, const _Alloc& __a)
597 	: c(std::move(__q.c), __a), comp(std::move(__q.comp)) { }
598 #endif
599 
600       /**
601        *  @brief  Builds a %queue from a range.
602        *  @param  __first  An input iterator.
603        *  @param  __last  An input iterator.
604        *  @param  __x  A comparison functor describing a strict weak ordering.
605        *  @param  __s  An initial sequence with which to start.
606        *
607        *  Begins by copying @a __s, inserting a copy of the elements
608        *  from @a [first,last) into the copy of @a __s, then ordering
609        *  the copy according to @a __x.
610        *
611        *  For more information on function objects, see the
612        *  documentation on @link functors functor base
613        *  classes@endlink.
614        */
615 #if __cplusplus < 201103L
616       template<typename _InputIterator>
617 	priority_queue(_InputIterator __first, _InputIterator __last,
618 		       const _Compare& __x = _Compare(),
619 		       const _Sequence& __s = _Sequence())
620 	: c(__s), comp(__x)
621 	{
622 	  __glibcxx_requires_valid_range(__first, __last);
623 	  c.insert(c.end(), __first, __last);
624 	  std::make_heap(c.begin(), c.end(), comp);
625 	}
626 #else
627       // _GLIBCXX_RESOLVE_LIB_DEFECTS
628       // 3529. priority_queue(first, last) should construct c with (first, last)
629       template<typename _InputIterator,
630 	       typename = std::_RequireInputIter<_InputIterator>>
631 	priority_queue(_InputIterator __first, _InputIterator __last,
632 		       const _Compare& __x = _Compare())
633 	: c(__first, __last), comp(__x)
634 	{ std::make_heap(c.begin(), c.end(), comp); }
635 
636       // _GLIBCXX_RESOLVE_LIB_DEFECTS
637       // 3522. Missing requirement on InputIterator template parameter
638       template<typename _InputIterator,
639 	       typename = std::_RequireInputIter<_InputIterator>>
640 	priority_queue(_InputIterator __first, _InputIterator __last,
641 		       const _Compare& __x, const _Sequence& __s)
642 	: c(__s), comp(__x)
643 	{
644 	  __glibcxx_requires_valid_range(__first, __last);
645 	  c.insert(c.end(), __first, __last);
646 	  std::make_heap(c.begin(), c.end(), comp);
647 	}
648 
649       template<typename _InputIterator,
650 	       typename = std::_RequireInputIter<_InputIterator>>
651 	priority_queue(_InputIterator __first, _InputIterator __last,
652 		       const _Compare& __x, _Sequence&& __s)
653 	: c(std::move(__s)), comp(__x)
654 	{
655 	  __glibcxx_requires_valid_range(__first, __last);
656 	  c.insert(c.end(), __first, __last);
657 	  std::make_heap(c.begin(), c.end(), comp);
658 	}
659 
660       // _GLIBCXX_RESOLVE_LIB_DEFECTS
661       // 3506. Missing allocator-extended constructors for priority_queue
662       template<typename _InputIterator, typename _Alloc,
663 	       typename = std::_RequireInputIter<_InputIterator>,
664 	       typename _Requires = _Uses<_Alloc>>
665 	priority_queue(_InputIterator __first, _InputIterator __last,
666 		       const _Alloc& __alloc)
667 	: c(__first, __last, __alloc), comp()
668 	{ std::make_heap(c.begin(), c.end(), comp); }
669 
670       template<typename _InputIterator, typename _Alloc,
671 	       typename = std::_RequireInputIter<_InputIterator>,
672 	       typename _Requires = _Uses<_Alloc>>
673 	priority_queue(_InputIterator __first, _InputIterator __last,
674 		       const _Compare& __x, const _Alloc& __alloc)
675 	: c(__first, __last, __alloc), comp(__x)
676 	{ std::make_heap(c.begin(), c.end(), comp); }
677 
678       template<typename _InputIterator, typename _Alloc,
679 	       typename = std::_RequireInputIter<_InputIterator>,
680 	       typename _Requires = _Uses<_Alloc>>
681 	priority_queue(_InputIterator __first, _InputIterator __last,
682 		       const _Compare& __x, const _Sequence& __s,
683 		       const _Alloc& __alloc)
684 	: c(__s, __alloc), comp(__x)
685 	{
686 	  __glibcxx_requires_valid_range(__first, __last);
687 	  c.insert(c.end(), __first, __last);
688 	  std::make_heap(c.begin(), c.end(), comp);
689 	}
690 
691       template<typename _InputIterator, typename _Alloc,
692 	       typename _Requires = _Uses<_Alloc>>
693 	priority_queue(_InputIterator __first, _InputIterator __last,
694 		       const _Compare& __x, _Sequence&& __s,
695 		       const _Alloc& __alloc)
696 	: c(std::move(__s), __alloc), comp(__x)
697 	{
698 	  __glibcxx_requires_valid_range(__first, __last);
699 	  c.insert(c.end(), __first, __last);
700 	  std::make_heap(c.begin(), c.end(), comp);
701 	}
702 #endif
703 
704       /**
705        *  Returns true if the %queue is empty.
706        */
707       _GLIBCXX_NODISCARD bool
708       empty() const
709       { return c.empty(); }
710 
711       /**  Returns the number of elements in the %queue.  */
712       _GLIBCXX_NODISCARD
713       size_type
714       size() const
715       { return c.size(); }
716 
717       /**
718        *  Returns a read-only (constant) reference to the data at the first
719        *  element of the %queue.
720        */
721       _GLIBCXX_NODISCARD
722       const_reference
723       top() const
724       {
725 	__glibcxx_requires_nonempty();
726 	return c.front();
727       }
728 
729       /**
730        *  @brief  Add data to the %queue.
731        *  @param  __x  Data to be added.
732        *
733        *  This is a typical %queue operation.
734        *  The time complexity of the operation depends on the underlying
735        *  sequence.
736        */
737       void
738       push(const value_type& __x)
739       {
740 	c.push_back(__x);
741 	std::push_heap(c.begin(), c.end(), comp);
742       }
743 
744 #if __cplusplus >= 201103L
745       void
746       push(value_type&& __x)
747       {
748 	c.push_back(std::move(__x));
749 	std::push_heap(c.begin(), c.end(), comp);
750       }
751 
752       template<typename... _Args>
753 	void
754 	emplace(_Args&&... __args)
755 	{
756 	  c.emplace_back(std::forward<_Args>(__args)...);
757 	  std::push_heap(c.begin(), c.end(), comp);
758 	}
759 #endif
760 
761       /**
762        *  @brief  Removes first element.
763        *
764        *  This is a typical %queue operation.  It shrinks the %queue
765        *  by one.  The time complexity of the operation depends on the
766        *  underlying sequence.
767        *
768        *  Note that no data is returned, and if the first element's
769        *  data is needed, it should be retrieved before pop() is
770        *  called.
771        */
772       void
773       pop()
774       {
775 	__glibcxx_requires_nonempty();
776 	std::pop_heap(c.begin(), c.end(), comp);
777 	c.pop_back();
778       }
779 
780 #if __cplusplus >= 201103L
781       void
782       swap(priority_queue& __pq)
783       noexcept(__and_<
784 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
785 		 __is_nothrow_swappable<_Sequence>,
786 #else
787 		 __is_nothrow_swappable<_Tp>,
788 #endif
789 		 __is_nothrow_swappable<_Compare>
790 	       >::value)
791       {
792 	using std::swap;
793 	swap(c, __pq.c);
794 	swap(comp, __pq.comp);
795       }
796 #endif // __cplusplus >= 201103L
797     };
798 
799 #if __cpp_deduction_guides >= 201606
800   template<typename _Compare, typename _Container,
801 	   typename = _RequireNotAllocator<_Compare>,
802 	   typename = _RequireNotAllocator<_Container>>
803     priority_queue(_Compare, _Container)
804     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
805 
806   template<typename _InputIterator, typename _ValT
807 	   = typename iterator_traits<_InputIterator>::value_type,
808 	   typename _Compare = less<_ValT>,
809 	   typename _Container = vector<_ValT>,
810 	   typename = _RequireInputIter<_InputIterator>,
811 	   typename = _RequireNotAllocator<_Compare>,
812 	   typename = _RequireNotAllocator<_Container>>
813     priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(),
814 		   _Container = _Container())
815     -> priority_queue<_ValT, _Container, _Compare>;
816 
817   template<typename _Compare, typename _Container, typename _Allocator,
818 	   typename = _RequireNotAllocator<_Compare>,
819 	   typename = _RequireNotAllocator<_Container>>
820     priority_queue(_Compare, _Container, _Allocator)
821     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
822 #endif
823 
824   // No equality/comparison operators are provided for priority_queue.
825 
826 #if __cplusplus >= 201103L
827   template<typename _Tp, typename _Sequence, typename _Compare>
828     inline
829 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
830     // Constrained free swap overload, see p0185r1
831     typename enable_if<__and_<__is_swappable<_Sequence>,
832 			      __is_swappable<_Compare>>::value>::type
833 #else
834     void
835 #endif
836     swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
837 	 priority_queue<_Tp, _Sequence, _Compare>& __y)
838     noexcept(noexcept(__x.swap(__y)))
839     { __x.swap(__y); }
840 
841   template<typename _Tp, typename _Sequence, typename _Compare,
842 	   typename _Alloc>
843     struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
844     : public uses_allocator<_Sequence, _Alloc>::type { };
845 #endif // __cplusplus >= 201103L
846 
847 _GLIBCXX_END_NAMESPACE_VERSION
848 } // namespace
849 
850 #endif /* _STL_QUEUE_H */
851