Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / queue
blob21c18ef431547140b825bf6d4fc62ec4240fb57e
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_QUEUE
11 #define _LIBCPP_QUEUE
14     queue synopsis
16 namespace std
19 template <class T, class Container = deque<T>>
20 class queue
22 public:
23     typedef Container                                container_type;
24     typedef typename container_type::value_type      value_type;
25     typedef typename container_type::reference       reference;
26     typedef typename container_type::const_reference const_reference;
27     typedef typename container_type::size_type       size_type;
29 protected:
30     container_type c;
32 public:
33     queue() = default;
34     ~queue() = default;
36     queue(const queue& q) = default;
37     queue(queue&& q) = default;
39     queue& operator=(const queue& q) = default;
40     queue& operator=(queue&& q) = default;
42     explicit queue(const container_type& c);
43     explicit queue(container_type&& c)
44     template<class InputIterator>
45         queue(InputIterator first, InputIterator last); // since C++23
46     template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23
47     template <class Alloc>
48         explicit queue(const Alloc& a);
49     template <class Alloc>
50         queue(const container_type& c, const Alloc& a);
51     template <class Alloc>
52         queue(container_type&& c, const Alloc& a);
53     template <class Alloc>
54         queue(const queue& q, const Alloc& a);
55     template <class Alloc>
56         queue(queue&& q, const Alloc& a);
57     template <class InputIterator, class Alloc>
58         queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
59     template<container-compatible-range<T> R, class Alloc>
60         queue(from_range_t, R&& rg, const Alloc&); // since C++23
62     bool      empty() const;
63     size_type size() const;
65     reference       front();
66     const_reference front() const;
67     reference       back();
68     const_reference back() const;
70     void push(const value_type& v);
71     void push(value_type&& v);
72     template<container-compatible-range<T> R>
73       void push_range(R&& rg); // C++23
74     template <class... Args> reference emplace(Args&&... args); // reference in C++17
75     void pop();
77     void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
80 template<class Container>
81   queue(Container) -> queue<typename Container::value_type, Container>; // C++17
83 template<class InputIterator>
84   queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
86 template<ranges::input_range R>
87   queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23
89 template<class Container, class Allocator>
90   queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
92 template<class InputIterator, class Allocator>
93   queue(InputIterator, InputIterator, Allocator)
94   -> queue<iter-value-type<InputIterator>,
95            deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
97 template<ranges::input_range R, class Allocator>
98     queue(from_range_t, R&&, Allocator)
99       -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
101 template <class T, class Container>
102   bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
104 template <class T, class Container>
105   bool operator< (const queue<T, Container>& x,const queue<T, Container>& y);
107 template <class T, class Container>
108   bool operator!=(const queue<T, Container>& x,const queue<T, Container>& y);
110 template <class T, class Container>
111   bool operator> (const queue<T, Container>& x,const queue<T, Container>& y);
113 template <class T, class Container>
114   bool operator>=(const queue<T, Container>& x,const queue<T, Container>& y);
116 template <class T, class Container>
117   bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y);
119 template<class T, three_way_comparable Container>
120   compare_three_way_result_t<Container>
121     operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);  // since C++20
123 template <class T, class Container>
124   void swap(queue<T, Container>& x, queue<T, Container>& y)
125   noexcept(noexcept(x.swap(y)));
127 template <class T, class Container = vector<T>,
128           class Compare = less<typename Container::value_type>>
129 class priority_queue
131 public:
132     typedef Container                                container_type;
133     typedef typename container_type::value_type      value_type;
134     typedef typename container_type::reference       reference;
135     typedef typename container_type::const_reference const_reference;
136     typedef typename container_type::size_type       size_type;
138 protected:
139     container_type c;
140     Compare comp;
142 public:
143     priority_queue() : priority_queue(Compare()) {} // C++20
144     explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
145     priority_queue(const Compare& x, const Container&);
146     explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); // before C++20
147     priority_queue(const Compare& x, Container&&); // C++20
148     template <class InputIterator>
149         priority_queue(InputIterator first, InputIterator last,
150                        const Compare& comp = Compare());
151     template <class InputIterator>
152         priority_queue(InputIterator first, InputIterator last,
153                        const Compare& comp, const Container& c);
154     template <class InputIterator>
155         priority_queue(InputIterator first, InputIterator last,
156                        const Compare& comp, Container&& c);
157     template <container-compatible-range<T> R>
158         priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23
159     template <class Alloc>
160         explicit priority_queue(const Alloc& a);
161     template <class Alloc>
162         priority_queue(const Compare& comp, const Alloc& a);
163     template <class Alloc>
164         priority_queue(const Compare& comp, const Container& c,
165                        const Alloc& a);
166     template <class Alloc>
167         priority_queue(const Compare& comp, Container&& c,
168                        const Alloc& a);
169     template <class InputIterator>
170         priority_queue(InputIterator first, InputIterator last,
171                        const Alloc& a);
172     template <class InputIterator>
173         priority_queue(InputIterator first, InputIterator last,
174                        const Compare& comp, const Alloc& a);
175     template <class InputIterator>
176         priority_queue(InputIterator first, InputIterator last,
177                        const Compare& comp, const Container& c, const Alloc& a);
178     template <class InputIterator>
179         priority_queue(InputIterator first, InputIterator last,
180                        const Compare& comp, Container&& c, const Alloc& a);
181     template <container-compatible-range<T> R, class Alloc>
182       priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23
183     template <container-compatible-range<T> R, class Alloc>
184       priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23
185     template <class Alloc>
186         priority_queue(const priority_queue& q, const Alloc& a);
187     template <class Alloc>
188         priority_queue(priority_queue&& q, const Alloc& a);
190     bool            empty() const;
191     size_type       size() const;
192     const_reference top() const;
194     void push(const value_type& v);
195     void push(value_type&& v);
196     template<container-compatible-range<T> R>
197       void push_range(R&& rg); // C++23
198     template <class... Args> void emplace(Args&&... args);
199     void pop();
201     void swap(priority_queue& q)
202         noexcept(is_nothrow_swappable_v<Container> &&
203                  is_nothrow_swappable_v<Comp>)
206 template <class Compare, class Container>
207 priority_queue(Compare, Container)
208     -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
210 template<class InputIterator,
211          class Compare = less<iter-value-type<InputIterator>>,
212          class Container = vector<iter-value-type<InputIterator>>>
213 priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
214     -> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17
216 template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
217   priority_queue(from_range_t, R&&, Compare = Compare())
218     -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23
220 template<class Compare, class Container, class Allocator>
221 priority_queue(Compare, Container, Allocator)
222     -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
224 template<class InputIterator, class Allocator>
225 priority_queue(InputIterator, InputIterator, Allocator)
226     -> priority_queue<iter-value-type<InputIterator>,
227                       vector<iter-value-type<InputIterator>, Allocator>,
228                       less<iter-value-type<InputIterator>>>; // C++17
230 template<class InputIterator, class Compare, class Allocator>
231 priority_queue(InputIterator, InputIterator, Compare, Allocator)
232     -> priority_queue<iter-value-type<InputIterator>,
233                       vector<iter-value-type<InputIterator>, Allocator>, Compare>; // C++17
235 template<class InputIterator, class Compare, class Container, class Allocator>
236 priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
237     -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
239 template<ranges::input_range R, class Compare, class Allocator>
240   priority_queue(from_range_t, R&&, Compare, Allocator)
241     -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
242                         Compare>; // C++23
244 template<ranges::input_range R, class Allocator>
245   priority_queue(from_range_t, R&&, Allocator)
246     -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23
248 template <class T, class Container, class Compare>
249   void swap(priority_queue<T, Container, Compare>& x,
250             priority_queue<T, Container, Compare>& y)
251             noexcept(noexcept(x.swap(y)));
253 }  // std
257 #include <__algorithm/make_heap.h>
258 #include <__algorithm/pop_heap.h>
259 #include <__algorithm/push_heap.h>
260 #include <__algorithm/ranges_copy.h>
261 #include <__assert> // all public C++ headers provide the assertion handler
262 #include <__config>
263 #include <__functional/operations.h>
264 #include <__iterator/back_insert_iterator.h>
265 #include <__iterator/iterator_traits.h>
266 #include <__memory/uses_allocator.h>
267 #include <__ranges/access.h>
268 #include <__ranges/concepts.h>
269 #include <__ranges/container_compatible_range.h>
270 #include <__ranges/from_range.h>
271 #include <__utility/forward.h>
272 #include <deque>
273 #include <vector>
274 #include <version>
276 // standard-mandated includes
278 // [queue.syn]
279 #include <compare>
280 #include <initializer_list>
282 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
283 #  pragma GCC system_header
284 #endif
286 _LIBCPP_BEGIN_NAMESPACE_STD
288 template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS queue;
290 template <class _Tp, class _Container>
291 _LIBCPP_INLINE_VISIBILITY
292 bool
293 operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);
295 template <class _Tp, class _Container>
296 _LIBCPP_INLINE_VISIBILITY
297 bool
298 operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);
300 template <class _Tp, class _Container /*= deque<_Tp>*/>
301 class _LIBCPP_TEMPLATE_VIS queue
303 public:
304     typedef _Container                               container_type;
305     typedef typename container_type::value_type      value_type;
306     typedef typename container_type::reference       reference;
307     typedef typename container_type::const_reference const_reference;
308     typedef typename container_type::size_type       size_type;
309     static_assert((is_same<_Tp, value_type>::value), "" );
311 protected:
312     container_type c;
314 public:
315     _LIBCPP_INLINE_VISIBILITY
316     queue()
317         _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
318         : c() {}
320     _LIBCPP_INLINE_VISIBILITY
321     queue(const queue& __q) : c(__q.c) {}
323 #if _LIBCPP_STD_VER >= 23
324     template <class _InputIterator,
325               class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
326     _LIBCPP_HIDE_FROM_ABI
327     queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
329     template <_ContainerCompatibleRange<_Tp> _Range>
330     _LIBCPP_HIDE_FROM_ABI
331     queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
333     template <class _InputIterator,
334               class _Alloc,
335               class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
336               class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
337     _LIBCPP_HIDE_FROM_ABI
338     queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}
340     template <_ContainerCompatibleRange<_Tp> _Range,
341               class _Alloc,
342               class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
343     _LIBCPP_HIDE_FROM_ABI
344     queue(from_range_t, _Range&& __range, const _Alloc& __alloc)
345       : c(from_range, std::forward<_Range>(__range), __alloc) {}
347 #endif
349     _LIBCPP_INLINE_VISIBILITY
350     queue& operator=(const queue& __q) {c = __q.c; return *this;}
352 #ifndef _LIBCPP_CXX03_LANG
353     _LIBCPP_INLINE_VISIBILITY
354     queue(queue&& __q)
355         _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
356         : c(_VSTD::move(__q.c)) {}
358     _LIBCPP_INLINE_VISIBILITY
359     queue& operator=(queue&& __q)
360         _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
361         {c = _VSTD::move(__q.c); return *this;}
362 #endif // _LIBCPP_CXX03_LANG
364     _LIBCPP_INLINE_VISIBILITY
365     explicit queue(const container_type& __c)  : c(__c) {}
366 #ifndef _LIBCPP_CXX03_LANG
367     _LIBCPP_INLINE_VISIBILITY
368     explicit queue(container_type&& __c) : c(_VSTD::move(__c)) {}
369 #endif // _LIBCPP_CXX03_LANG
370     template <class _Alloc>
371         _LIBCPP_INLINE_VISIBILITY
372         explicit queue(const _Alloc& __a,
373                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
374             : c(__a) {}
375     template <class _Alloc>
376         _LIBCPP_INLINE_VISIBILITY
377         queue(const queue& __q, const _Alloc& __a,
378                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
379             : c(__q.c, __a) {}
380     template <class _Alloc>
381         _LIBCPP_INLINE_VISIBILITY
382         queue(const container_type& __c, const _Alloc& __a,
383                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
384             : c(__c, __a) {}
385 #ifndef _LIBCPP_CXX03_LANG
386     template <class _Alloc>
387         _LIBCPP_INLINE_VISIBILITY
388         queue(container_type&& __c, const _Alloc& __a,
389                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
390             : c(_VSTD::move(__c), __a) {}
391     template <class _Alloc>
392         _LIBCPP_INLINE_VISIBILITY
393         queue(queue&& __q, const _Alloc& __a,
394                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
395             : c(_VSTD::move(__q.c), __a) {}
397 #endif // _LIBCPP_CXX03_LANG
399     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
400     bool      empty() const {return c.empty();}
401     _LIBCPP_INLINE_VISIBILITY
402     size_type size() const  {return c.size();}
404     _LIBCPP_INLINE_VISIBILITY
405     reference       front()       {return c.front();}
406     _LIBCPP_INLINE_VISIBILITY
407     const_reference front() const {return c.front();}
408     _LIBCPP_INLINE_VISIBILITY
409     reference       back()        {return c.back();}
410     _LIBCPP_INLINE_VISIBILITY
411     const_reference back() const  {return c.back();}
413     _LIBCPP_INLINE_VISIBILITY
414     void push(const value_type& __v) {c.push_back(__v);}
415 #ifndef _LIBCPP_CXX03_LANG
416     _LIBCPP_INLINE_VISIBILITY
417     void push(value_type&& __v)      {c.push_back(_VSTD::move(__v));}
419 #if _LIBCPP_STD_VER >= 23
420     template <_ContainerCompatibleRange<_Tp> _Range>
421     _LIBCPP_HIDE_FROM_ABI
422     void push_range(_Range&& __range) {
423       if constexpr (requires (container_type& __c) {
424         __c.append_range(std::forward<_Range>(__range));
425       }) {
426         c.append_range(std::forward<_Range>(__range));
427       } else {
428         ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
429       }
430     }
431 #endif
433     template <class... _Args>
434         _LIBCPP_INLINE_VISIBILITY
435 #if _LIBCPP_STD_VER >= 17
436         decltype(auto) emplace(_Args&&... __args)
437             { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
438 #else
439         void     emplace(_Args&&... __args)
440             {        c.emplace_back(_VSTD::forward<_Args>(__args)...);}
441 #endif
442 #endif // _LIBCPP_CXX03_LANG
443     _LIBCPP_INLINE_VISIBILITY
444     void pop() {c.pop_front();}
446     _LIBCPP_INLINE_VISIBILITY
447     void swap(queue& __q)
448         _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)
449     {
450         using _VSTD::swap;
451         swap(c, __q.c);
452     }
454     _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
456     template <class _T1, class _OtherContainer>
457     friend
458     _LIBCPP_INLINE_VISIBILITY
459     bool
460     operator==(const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
462     template <class _T1, class _OtherContainer>
463     friend
464     _LIBCPP_INLINE_VISIBILITY
465     bool
466     operator< (const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
469 #if _LIBCPP_STD_VER >= 17
470 template<class _Container,
471          class = enable_if_t<!__is_allocator<_Container>::value>
473 queue(_Container)
474     -> queue<typename _Container::value_type, _Container>;
476 template<class _Container,
477          class _Alloc,
478          class = enable_if_t<!__is_allocator<_Container>::value>,
479          class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
481 queue(_Container, _Alloc)
482     -> queue<typename _Container::value_type, _Container>;
483 #endif
485 #if _LIBCPP_STD_VER >= 23
486 template <class _InputIterator,
487           class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
488 queue(_InputIterator, _InputIterator)
489     -> queue<__iter_value_type<_InputIterator>>;
491 template <ranges::input_range _Range>
492 queue(from_range_t, _Range&&)
493     -> queue<ranges::range_value_t<_Range>>;
495 template <class _InputIterator,
496           class _Alloc,
497           class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
498           class = __enable_if_t<__is_allocator<_Alloc>::value>>
499 queue(_InputIterator, _InputIterator, _Alloc)
500     -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
502 template <ranges::input_range _Range,
503           class _Alloc,
504           class = __enable_if_t<__is_allocator<_Alloc>::value>>
505 queue(from_range_t, _Range&&, _Alloc)
506     -> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
507 #endif
509 template <class _Tp, class _Container>
510 inline _LIBCPP_INLINE_VISIBILITY
511 bool
512 operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
514     return __x.c == __y.c;
517 template <class _Tp, class _Container>
518 inline _LIBCPP_INLINE_VISIBILITY
519 bool
520 operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
522     return __x.c < __y.c;
525 template <class _Tp, class _Container>
526 inline _LIBCPP_INLINE_VISIBILITY
527 bool
528 operator!=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
530     return !(__x == __y);
533 template <class _Tp, class _Container>
534 inline _LIBCPP_INLINE_VISIBILITY
535 bool
536 operator> (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
538     return __y < __x;
541 template <class _Tp, class _Container>
542 inline _LIBCPP_INLINE_VISIBILITY
543 bool
544 operator>=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
546     return !(__x < __y);
549 template <class _Tp, class _Container>
550 inline _LIBCPP_INLINE_VISIBILITY
551 bool
552 operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
554     return !(__y < __x);
557 #if _LIBCPP_STD_VER >= 20
559 template <class _Tp, three_way_comparable _Container>
560 _LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container>
561 operator<=>(const queue<_Tp, _Container>& __x, const queue<_Tp, _Container>& __y) {
562     // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors
563     return __x.__get_container() <=> __y.__get_container();
566 #endif
568 template <class _Tp, class _Container, __enable_if_t<__is_swappable<_Container>::value, int> = 0>
569 inline _LIBCPP_INLINE_VISIBILITY
570 void
571 swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y)
572     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
574     __x.swap(__y);
577 template <class _Tp, class _Container, class _Alloc>
578 struct _LIBCPP_TEMPLATE_VIS uses_allocator<queue<_Tp, _Container>, _Alloc>
579     : public uses_allocator<_Container, _Alloc>
583 template <class _Tp, class _Container = vector<_Tp>,
584           class _Compare = less<typename _Container::value_type> >
585 class _LIBCPP_TEMPLATE_VIS priority_queue
587 public:
588     typedef _Container                               container_type;
589     typedef _Compare                                 value_compare;
590     typedef typename container_type::value_type      value_type;
591     typedef typename container_type::reference       reference;
592     typedef typename container_type::const_reference const_reference;
593     typedef typename container_type::size_type       size_type;
594     static_assert((is_same<_Tp, value_type>::value), "" );
596 protected:
597     container_type c;
598     value_compare comp;
600 public:
601     _LIBCPP_INLINE_VISIBILITY
602     priority_queue()
603         _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value &&
604                    is_nothrow_default_constructible<value_compare>::value)
605         : c(), comp() {}
607     _LIBCPP_INLINE_VISIBILITY
608     priority_queue(const priority_queue& __q) : c(__q.c), comp(__q.comp) {}
610     _LIBCPP_INLINE_VISIBILITY
611     priority_queue& operator=(const priority_queue& __q)
612         {c = __q.c; comp = __q.comp; return *this;}
614 #ifndef _LIBCPP_CXX03_LANG
615     _LIBCPP_INLINE_VISIBILITY
616     priority_queue(priority_queue&& __q)
617         _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value &&
618                    is_nothrow_move_constructible<value_compare>::value)
619         : c(_VSTD::move(__q.c)), comp(_VSTD::move(__q.comp)) {}
621     _LIBCPP_INLINE_VISIBILITY
622     priority_queue& operator=(priority_queue&& __q)
623         _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value &&
624                    is_nothrow_move_assignable<value_compare>::value)
625         {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}
626 #endif // _LIBCPP_CXX03_LANG
628     _LIBCPP_INLINE_VISIBILITY
629     explicit priority_queue(const value_compare& __comp)
630         : c(), comp(__comp) {}
631     _LIBCPP_INLINE_VISIBILITY
632     priority_queue(const value_compare& __comp, const container_type& __c);
633 #ifndef _LIBCPP_CXX03_LANG
634     _LIBCPP_INLINE_VISIBILITY
635     priority_queue(const value_compare& __comp, container_type&& __c);
636 #endif
637     template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
638         _LIBCPP_INLINE_VISIBILITY
639         priority_queue(_InputIter __f, _InputIter __l,
640                        const value_compare& __comp = value_compare());
641     template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
642         _LIBCPP_INLINE_VISIBILITY
643         priority_queue(_InputIter __f, _InputIter __l,
644                        const value_compare& __comp, const container_type& __c);
645 #ifndef _LIBCPP_CXX03_LANG
646     template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
647         _LIBCPP_INLINE_VISIBILITY
648         priority_queue(_InputIter __f, _InputIter __l,
649                        const value_compare& __comp, container_type&& __c);
650 #endif // _LIBCPP_CXX03_LANG
652 #if _LIBCPP_STD_VER >= 23
653     template <_ContainerCompatibleRange<_Tp> _Range>
654     _LIBCPP_HIDE_FROM_ABI
655     priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare())
656     : c(from_range, std::forward<_Range>(__range)),
657       comp(__comp) {
658       std::make_heap(c.begin(), c.end(), comp);
659     }
660 #endif
662     template <class _Alloc>
663         _LIBCPP_INLINE_VISIBILITY
664         explicit priority_queue(const _Alloc& __a,
665                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
666     template <class _Alloc>
667         _LIBCPP_INLINE_VISIBILITY
668         priority_queue(const value_compare& __comp, const _Alloc& __a,
669                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
670     template <class _Alloc>
671         _LIBCPP_INLINE_VISIBILITY
672         priority_queue(const value_compare& __comp, const container_type& __c,
673                        const _Alloc& __a,
674                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
675     template <class _Alloc>
676         _LIBCPP_INLINE_VISIBILITY
677         priority_queue(const priority_queue& __q, const _Alloc& __a,
678                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
679 #ifndef _LIBCPP_CXX03_LANG
680     template <class _Alloc>
681         _LIBCPP_INLINE_VISIBILITY
682         priority_queue(const value_compare& __comp, container_type&& __c,
683                        const _Alloc& __a,
684                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
685     template <class _Alloc>
686         _LIBCPP_INLINE_VISIBILITY
687         priority_queue(priority_queue&& __q, const _Alloc& __a,
688                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
689 #endif // _LIBCPP_CXX03_LANG
691     template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
692         _LIBCPP_INLINE_VISIBILITY
693         priority_queue(_InputIter __f, _InputIter __l, const _Alloc& __a,
694                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
696     template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
697         _LIBCPP_INLINE_VISIBILITY
698         priority_queue(_InputIter __f, _InputIter __l,
699                        const value_compare& __comp, const _Alloc& __a,
700                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
702     template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
703         _LIBCPP_INLINE_VISIBILITY
704         priority_queue(_InputIter __f, _InputIter __l,
705                        const value_compare& __comp, const container_type& __c, const _Alloc& __a,
706                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
708 #ifndef _LIBCPP_CXX03_LANG
709     template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
710         _LIBCPP_INLINE_VISIBILITY
711         priority_queue(_InputIter __f, _InputIter __l,
712                        const value_compare& __comp, container_type&& __c, const _Alloc& __a,
713                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
714 #endif  // _LIBCPP_CXX03_LANG
716 #if _LIBCPP_STD_VER >= 23
718     template <_ContainerCompatibleRange<_Tp> _Range,
719               class _Alloc,
720               class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
721     _LIBCPP_HIDE_FROM_ABI
722     priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a)
723     : c(from_range, std::forward<_Range>(__range), __a),
724       comp(__comp) {
725       std::make_heap(c.begin(), c.end(), comp);
726     }
728     template <_ContainerCompatibleRange<_Tp> _Range,
729               class _Alloc,
730               class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
731     _LIBCPP_HIDE_FROM_ABI
732     priority_queue(from_range_t, _Range&& __range, const _Alloc& __a)
733     : c(from_range, std::forward<_Range>(__range), __a),
734       comp() {
735       std::make_heap(c.begin(), c.end(), comp);
736     }
738 #endif
740     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
741     bool            empty() const {return c.empty();}
742     _LIBCPP_INLINE_VISIBILITY
743     size_type       size() const  {return c.size();}
744     _LIBCPP_INLINE_VISIBILITY
745     const_reference top() const   {return c.front();}
747     _LIBCPP_INLINE_VISIBILITY
748     void push(const value_type& __v);
749 #ifndef _LIBCPP_CXX03_LANG
750     _LIBCPP_INLINE_VISIBILITY
751     void push(value_type&& __v);
753 #if _LIBCPP_STD_VER >= 23
754     template <_ContainerCompatibleRange<_Tp> _Range>
755     _LIBCPP_HIDE_FROM_ABI
756     void push_range(_Range&& __range) {
757       if constexpr (requires (container_type& __c) {
758         __c.append_range(std::forward<_Range>(__range));
759       }) {
760         c.append_range(std::forward<_Range>(__range));
761       } else {
762         ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
763       }
765       std::make_heap(c.begin(), c.end(), comp);
766     }
767 #endif
769     template <class... _Args>
770     _LIBCPP_INLINE_VISIBILITY
771     void emplace(_Args&&... __args);
772 #endif // _LIBCPP_CXX03_LANG
773     _LIBCPP_INLINE_VISIBILITY
774     void pop();
776     _LIBCPP_INLINE_VISIBILITY
777     void swap(priority_queue& __q)
778         _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
779                    __is_nothrow_swappable<value_compare>::value);
781     _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
784 #if _LIBCPP_STD_VER >= 17
785 template <class _Compare,
786           class _Container,
787           class = enable_if_t<!__is_allocator<_Compare>::value>,
788           class = enable_if_t<!__is_allocator<_Container>::value>
790 priority_queue(_Compare, _Container)
791     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
793 template<class _InputIterator,
794          class _Compare = less<__iter_value_type<_InputIterator>>,
795          class _Container = vector<__iter_value_type<_InputIterator>>,
796          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
797          class = enable_if_t<!__is_allocator<_Compare>::value>,
798          class = enable_if_t<!__is_allocator<_Container>::value>
800 priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container())
801     -> priority_queue<__iter_value_type<_InputIterator>, _Container, _Compare>;
803 template<class _Compare,
804          class _Container,
805          class _Alloc,
806          class = enable_if_t<!__is_allocator<_Compare>::value>,
807          class = enable_if_t<!__is_allocator<_Container>::value>,
808          class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
810 priority_queue(_Compare, _Container, _Alloc)
811     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
813 template<class _InputIterator, class _Allocator,
814          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
815          class = enable_if_t<__is_allocator<_Allocator>::value>
817 priority_queue(_InputIterator, _InputIterator, _Allocator)
818     -> priority_queue<__iter_value_type<_InputIterator>,
819                       vector<__iter_value_type<_InputIterator>, _Allocator>,
820                       less<__iter_value_type<_InputIterator>>>;
822 template<class _InputIterator, class _Compare, class _Allocator,
823          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
824          class = enable_if_t<!__is_allocator<_Compare>::value>,
825          class = enable_if_t<__is_allocator<_Allocator>::value>
827 priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator)
828     -> priority_queue<__iter_value_type<_InputIterator>,
829                       vector<__iter_value_type<_InputIterator>, _Allocator>, _Compare>;
831 template<class _InputIterator, class _Compare, class _Container, class _Alloc,
832          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
833          class = enable_if_t<!__is_allocator<_Compare>::value>,
834          class = enable_if_t<!__is_allocator<_Container>::value>,
835          class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
837 priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
838     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
839 #endif
841 #if _LIBCPP_STD_VER >= 23
843 template <ranges::input_range _Range,
844           class _Compare = less<ranges::range_value_t<_Range>>,
845           class = enable_if_t<!__is_allocator<_Compare>::value>>
846 priority_queue(from_range_t, _Range&&, _Compare = _Compare())
847     -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;
849 template <ranges::input_range _Range,
850           class _Compare,
851           class _Alloc,
852           class = enable_if_t<!__is_allocator<_Compare>::value>,
853           class = enable_if_t<__is_allocator<_Alloc>::value>>
854 priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
855     -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>,
856                         _Compare>;
858 template <ranges::input_range _Range,
859           class _Alloc,
860           class = enable_if_t<__is_allocator<_Alloc>::value>>
861 priority_queue(from_range_t, _Range&&, _Alloc)
862     -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;
864 #endif
866 template <class _Tp, class _Container, class _Compare>
867 inline
868 priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
869                                                           const container_type& __c)
870     : c(__c),
871       comp(__comp)
873     _VSTD::make_heap(c.begin(), c.end(), comp);
876 #ifndef _LIBCPP_CXX03_LANG
878 template <class _Tp, class _Container, class _Compare>
879 inline
880 priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
881                                                           container_type&& __c)
882     : c(_VSTD::move(__c)),
883       comp(__comp)
885     _VSTD::make_heap(c.begin(), c.end(), comp);
888 #endif // _LIBCPP_CXX03_LANG
890 template <class _Tp, class _Container, class _Compare>
891 template <class _InputIter, class>
892 inline
893 priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
894                                                           const value_compare& __comp)
895     : c(__f, __l),
896       comp(__comp)
898     _VSTD::make_heap(c.begin(), c.end(), comp);
901 template <class _Tp, class _Container, class _Compare>
902 template <class _InputIter, class>
903 inline
904 priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
905                                                           const value_compare& __comp,
906                                                           const container_type& __c)
907     : c(__c),
908       comp(__comp)
910     c.insert(c.end(), __f, __l);
911     _VSTD::make_heap(c.begin(), c.end(), comp);
914 #ifndef _LIBCPP_CXX03_LANG
916 template <class _Tp, class _Container, class _Compare>
917 template <class _InputIter, class>
918 inline
919 priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
920                                                           const value_compare& __comp,
921                                                           container_type&& __c)
922     : c(_VSTD::move(__c)),
923       comp(__comp)
925     c.insert(c.end(), __f, __l);
926     _VSTD::make_heap(c.begin(), c.end(), comp);
929 #endif // _LIBCPP_CXX03_LANG
931 template <class _Tp, class _Container, class _Compare>
932 template <class _Alloc>
933 inline
934 priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a,
935                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
936     : c(__a)
940 template <class _Tp, class _Container, class _Compare>
941 template <class _Alloc>
942 inline
943 priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
944                                                           const _Alloc& __a,
945                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
946     : c(__a),
947       comp(__comp)
951 template <class _Tp, class _Container, class _Compare>
952 template <class _Alloc>
953 inline
954 priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
955                                                           const container_type& __c,
956                                                           const _Alloc& __a,
957                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
958     : c(__c, __a),
959       comp(__comp)
961     _VSTD::make_heap(c.begin(), c.end(), comp);
964 template <class _Tp, class _Container, class _Compare>
965 template <class _Alloc>
966 inline
967 priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q,
968                                                           const _Alloc& __a,
969                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
970     : c(__q.c, __a),
971       comp(__q.comp)
975 #ifndef _LIBCPP_CXX03_LANG
977 template <class _Tp, class _Container, class _Compare>
978 template <class _Alloc>
979 inline
980 priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
981                                                           container_type&& __c,
982                                                           const _Alloc& __a,
983                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
984     : c(_VSTD::move(__c), __a),
985       comp(__comp)
987     _VSTD::make_heap(c.begin(), c.end(), comp);
990 template <class _Tp, class _Container, class _Compare>
991 template <class _Alloc>
992 inline
993 priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q,
994                                                           const _Alloc& __a,
995                        __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
996     : c(_VSTD::move(__q.c), __a),
997       comp(_VSTD::move(__q.comp))
1001 #endif  // _LIBCPP_CXX03_LANG
1003 template <class _Tp, class _Container, class _Compare>
1004 template <class _InputIter, class _Alloc, class>
1005 inline
1006 priority_queue<_Tp, _Container, _Compare>::priority_queue(
1007         _InputIter __f, _InputIter __l, const _Alloc& __a,
1008         __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
1009     : c(__f, __l, __a),
1010       comp()
1012     _VSTD::make_heap(c.begin(), c.end(), comp);
1015 template <class _Tp, class _Container, class _Compare>
1016 template <class _InputIter, class _Alloc, class>
1017 inline
1018 priority_queue<_Tp, _Container, _Compare>::priority_queue(
1019         _InputIter __f, _InputIter __l,
1020         const value_compare& __comp, const _Alloc& __a,
1021         __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
1022     : c(__f, __l, __a),
1023       comp(__comp)
1025     _VSTD::make_heap(c.begin(), c.end(), comp);
1028 template <class _Tp, class _Container, class _Compare>
1029 template <class _InputIter, class _Alloc, class>
1030 inline
1031 priority_queue<_Tp, _Container, _Compare>::priority_queue(
1032         _InputIter __f, _InputIter __l,
1033         const value_compare& __comp, const container_type& __c, const _Alloc& __a,
1034         __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
1035     : c(__c, __a),
1036       comp(__comp)
1038     c.insert(c.end(), __f, __l);
1039     _VSTD::make_heap(c.begin(), c.end(), comp);
1042 #ifndef _LIBCPP_CXX03_LANG
1043 template <class _Tp, class _Container, class _Compare>
1044 template <class _InputIter, class _Alloc, class>
1045 inline
1046 priority_queue<_Tp, _Container, _Compare>::priority_queue(
1047         _InputIter __f, _InputIter __l, const value_compare& __comp,
1048         container_type&& __c, const _Alloc& __a,
1049         __enable_if_t<uses_allocator<container_type, _Alloc>::value>*)
1050     : c(_VSTD::move(__c), __a),
1051       comp(__comp)
1053     c.insert(c.end(), __f, __l);
1054     _VSTD::make_heap(c.begin(), c.end(), comp);
1056 #endif  // _LIBCPP_CXX03_LANG
1058 template <class _Tp, class _Container, class _Compare>
1059 inline
1060 void
1061 priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v)
1063     c.push_back(__v);
1064     _VSTD::push_heap(c.begin(), c.end(), comp);
1067 #ifndef _LIBCPP_CXX03_LANG
1069 template <class _Tp, class _Container, class _Compare>
1070 inline
1071 void
1072 priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v)
1074     c.push_back(_VSTD::move(__v));
1075     _VSTD::push_heap(c.begin(), c.end(), comp);
1078 template <class _Tp, class _Container, class _Compare>
1079 template <class... _Args>
1080 inline
1081 void
1082 priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args)
1084     c.emplace_back(_VSTD::forward<_Args>(__args)...);
1085     _VSTD::push_heap(c.begin(), c.end(), comp);
1088 #endif // _LIBCPP_CXX03_LANG
1090 template <class _Tp, class _Container, class _Compare>
1091 inline
1092 void
1093 priority_queue<_Tp, _Container, _Compare>::pop()
1095     _VSTD::pop_heap(c.begin(), c.end(), comp);
1096     c.pop_back();
1099 template <class _Tp, class _Container, class _Compare>
1100 inline
1101 void
1102 priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q)
1103         _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
1104                    __is_nothrow_swappable<value_compare>::value)
1106     using _VSTD::swap;
1107     swap(c, __q.c);
1108     swap(comp, __q.comp);
1111 template <class _Tp, class _Container, class _Compare,
1112           __enable_if_t<__is_swappable<_Container>::value && __is_swappable<_Compare>::value, int> = 0>
1113 inline _LIBCPP_INLINE_VISIBILITY
1114 void
1115 swap(priority_queue<_Tp, _Container, _Compare>& __x,
1116      priority_queue<_Tp, _Container, _Compare>& __y)
1117     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1119     __x.swap(__y);
1122 template <class _Tp, class _Container, class _Compare, class _Alloc>
1123 struct _LIBCPP_TEMPLATE_VIS uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc>
1124     : public uses_allocator<_Container, _Alloc>
1128 _LIBCPP_END_NAMESPACE_STD
1130 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1131 #  include <concepts>
1132 #  include <cstdlib>
1133 #  include <functional>
1134 #  include <type_traits>
1135 #endif
1137 #endif // _LIBCPP_QUEUE