xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Queue implementation -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /*
2638fd1498Szrj  *
2738fd1498Szrj  * Copyright (c) 1994
2838fd1498Szrj  * Hewlett-Packard Company
2938fd1498Szrj  *
3038fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
3138fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
3238fd1498Szrj  * provided that the above copyright notice appear in all copies and
3338fd1498Szrj  * that both that copyright notice and this permission notice appear
3438fd1498Szrj  * in supporting documentation.  Hewlett-Packard Company makes no
3538fd1498Szrj  * representations about the suitability of this software for any
3638fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
3738fd1498Szrj  *
3838fd1498Szrj  *
3938fd1498Szrj  * Copyright (c) 1996,1997
4038fd1498Szrj  * Silicon Graphics Computer Systems, Inc.
4138fd1498Szrj  *
4238fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
4338fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
4438fd1498Szrj  * provided that the above copyright notice appear in all copies and
4538fd1498Szrj  * that both that copyright notice and this permission notice appear
4638fd1498Szrj  * in supporting documentation.  Silicon Graphics makes no
4738fd1498Szrj  * representations about the suitability of this software for any
4838fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
4938fd1498Szrj  */
5038fd1498Szrj 
5138fd1498Szrj /** @file bits/stl_queue.h
5238fd1498Szrj  *  This is an internal header file, included by other library headers.
5338fd1498Szrj  *  Do not attempt to use it directly. @headername{queue}
5438fd1498Szrj  */
5538fd1498Szrj 
5638fd1498Szrj #ifndef _STL_QUEUE_H
5738fd1498Szrj #define _STL_QUEUE_H 1
5838fd1498Szrj 
5938fd1498Szrj #include <bits/concept_check.h>
6038fd1498Szrj #include <debug/debug.h>
6138fd1498Szrj #if __cplusplus >= 201103L
6238fd1498Szrj # include <bits/uses_allocator.h>
6338fd1498Szrj #endif
6438fd1498Szrj 
_GLIBCXX_VISIBILITY(default)6538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
6638fd1498Szrj {
6738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
6838fd1498Szrj 
6938fd1498Szrj   /**
7038fd1498Szrj    *  @brief  A standard container giving FIFO behavior.
7138fd1498Szrj    *
7238fd1498Szrj    *  @ingroup sequences
7338fd1498Szrj    *
7438fd1498Szrj    *  @tparam _Tp  Type of element.
7538fd1498Szrj    *  @tparam _Sequence  Type of underlying sequence, defaults to deque<_Tp>.
7638fd1498Szrj    *
7738fd1498Szrj    *  Meets many of the requirements of a
7838fd1498Szrj    *  <a href="tables.html#65">container</a>,
7938fd1498Szrj    *  but does not define anything to do with iterators.  Very few of the
8038fd1498Szrj    *  other standard container interfaces are defined.
8138fd1498Szrj    *
8238fd1498Szrj    *  This is not a true container, but an @e adaptor.  It holds another
8338fd1498Szrj    *  container, and provides a wrapper interface to that container.  The
8438fd1498Szrj    *  wrapper is what enforces strict first-in-first-out %queue behavior.
8538fd1498Szrj    *
8638fd1498Szrj    *  The second template parameter defines the type of the underlying
8738fd1498Szrj    *  sequence/container.  It defaults to std::deque, but it can be any type
8838fd1498Szrj    *  that supports @c front, @c back, @c push_back, and @c pop_front,
8938fd1498Szrj    *  such as std::list or an appropriate user-defined type.
9038fd1498Szrj    *
9138fd1498Szrj    *  Members not found in @a normal containers are @c container_type,
9238fd1498Szrj    *  which is a typedef for the second Sequence parameter, and @c push and
9338fd1498Szrj    *  @c pop, which are standard %queue/FIFO operations.
9438fd1498Szrj   */
9538fd1498Szrj   template<typename _Tp, typename _Sequence = deque<_Tp> >
9638fd1498Szrj     class queue
9738fd1498Szrj     {
9838fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS
9938fd1498Szrj       // concept requirements
10038fd1498Szrj       typedef typename _Sequence::value_type _Sequence_value_type;
10138fd1498Szrj # if __cplusplus < 201103L
10238fd1498Szrj       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
10338fd1498Szrj # endif
10438fd1498Szrj       __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
10538fd1498Szrj       __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
10638fd1498Szrj       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
10738fd1498Szrj #endif
10838fd1498Szrj 
10938fd1498Szrj       template<typename _Tp1, typename _Seq1>
11038fd1498Szrj 	friend bool
11138fd1498Szrj 	operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
11238fd1498Szrj 
11338fd1498Szrj       template<typename _Tp1, typename _Seq1>
11438fd1498Szrj 	friend bool
11538fd1498Szrj 	operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
11638fd1498Szrj 
11738fd1498Szrj #if __cplusplus >= 201103L
11838fd1498Szrj       template<typename _Alloc>
11938fd1498Szrj 	using _Uses = typename
12038fd1498Szrj 	  enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
12138fd1498Szrj #endif
12238fd1498Szrj 
12338fd1498Szrj     public:
12438fd1498Szrj       typedef typename	_Sequence::value_type		value_type;
12538fd1498Szrj       typedef typename	_Sequence::reference		reference;
12638fd1498Szrj       typedef typename	_Sequence::const_reference	const_reference;
12738fd1498Szrj       typedef typename	_Sequence::size_type		size_type;
12838fd1498Szrj       typedef		_Sequence			container_type;
12938fd1498Szrj 
13038fd1498Szrj     protected:
13138fd1498Szrj       /*  Maintainers wondering why this isn't uglified as per style
13238fd1498Szrj        *  guidelines should note that this name is specified in the standard,
13338fd1498Szrj        *  C++98 [23.2.3.1].
13438fd1498Szrj        *  (Why? Presumably for the same reason that it's protected instead
13538fd1498Szrj        *  of private: to allow derivation.  But none of the other
13638fd1498Szrj        *  containers allow for derivation.  Odd.)
13738fd1498Szrj        */
13838fd1498Szrj        ///  @c c is the underlying container.
13938fd1498Szrj       _Sequence c;
14038fd1498Szrj 
14138fd1498Szrj     public:
14238fd1498Szrj       /**
14338fd1498Szrj        *  @brief  Default constructor creates no elements.
14438fd1498Szrj        */
14538fd1498Szrj #if __cplusplus < 201103L
14638fd1498Szrj       explicit
14738fd1498Szrj       queue(const _Sequence& __c = _Sequence())
14838fd1498Szrj       : c(__c) { }
14938fd1498Szrj #else
15038fd1498Szrj       template<typename _Seq = _Sequence, typename _Requires = typename
15138fd1498Szrj 	       enable_if<is_default_constructible<_Seq>::value>::type>
15238fd1498Szrj 	queue()
15338fd1498Szrj 	: c() { }
15438fd1498Szrj 
15538fd1498Szrj       explicit
15638fd1498Szrj       queue(const _Sequence& __c)
15738fd1498Szrj       : c(__c) { }
15838fd1498Szrj 
15938fd1498Szrj       explicit
16038fd1498Szrj       queue(_Sequence&& __c)
16138fd1498Szrj       : c(std::move(__c)) { }
16238fd1498Szrj 
16338fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
16438fd1498Szrj 	explicit
16538fd1498Szrj 	queue(const _Alloc& __a)
16638fd1498Szrj 	: c(__a) { }
16738fd1498Szrj 
16838fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
16938fd1498Szrj 	queue(const _Sequence& __c, const _Alloc& __a)
17038fd1498Szrj 	: c(__c, __a) { }
17138fd1498Szrj 
17238fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
17338fd1498Szrj 	queue(_Sequence&& __c, const _Alloc& __a)
17438fd1498Szrj 	: c(std::move(__c), __a) { }
17538fd1498Szrj 
17638fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
17738fd1498Szrj 	queue(const queue& __q, const _Alloc& __a)
17838fd1498Szrj 	: c(__q.c, __a) { }
17938fd1498Szrj 
18038fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
18138fd1498Szrj 	queue(queue&& __q, const _Alloc& __a)
18238fd1498Szrj 	: c(std::move(__q.c), __a) { }
18338fd1498Szrj #endif
18438fd1498Szrj 
18538fd1498Szrj       /**
18638fd1498Szrj        *  Returns true if the %queue is empty.
18738fd1498Szrj        */
18838fd1498Szrj       bool
18938fd1498Szrj       empty() const
19038fd1498Szrj       { return c.empty(); }
19138fd1498Szrj 
19238fd1498Szrj       /**  Returns the number of elements in the %queue.  */
19338fd1498Szrj       size_type
19438fd1498Szrj       size() const
19538fd1498Szrj       { return c.size(); }
19638fd1498Szrj 
19738fd1498Szrj       /**
19838fd1498Szrj        *  Returns a read/write reference to the data at the first
19938fd1498Szrj        *  element of the %queue.
20038fd1498Szrj        */
20138fd1498Szrj       reference
20238fd1498Szrj       front()
20338fd1498Szrj       {
20438fd1498Szrj 	__glibcxx_requires_nonempty();
20538fd1498Szrj 	return c.front();
20638fd1498Szrj       }
20738fd1498Szrj 
20838fd1498Szrj       /**
20938fd1498Szrj        *  Returns a read-only (constant) reference to the data at the first
21038fd1498Szrj        *  element of the %queue.
21138fd1498Szrj        */
21238fd1498Szrj       const_reference
21338fd1498Szrj       front() const
21438fd1498Szrj       {
21538fd1498Szrj 	__glibcxx_requires_nonempty();
21638fd1498Szrj 	return c.front();
21738fd1498Szrj       }
21838fd1498Szrj 
21938fd1498Szrj       /**
22038fd1498Szrj        *  Returns a read/write reference to the data at the last
22138fd1498Szrj        *  element of the %queue.
22238fd1498Szrj        */
22338fd1498Szrj       reference
22438fd1498Szrj       back()
22538fd1498Szrj       {
22638fd1498Szrj 	__glibcxx_requires_nonempty();
22738fd1498Szrj 	return c.back();
22838fd1498Szrj       }
22938fd1498Szrj 
23038fd1498Szrj       /**
23138fd1498Szrj        *  Returns a read-only (constant) reference to the data at the last
23238fd1498Szrj        *  element of the %queue.
23338fd1498Szrj        */
23438fd1498Szrj       const_reference
23538fd1498Szrj       back() const
23638fd1498Szrj       {
23738fd1498Szrj 	__glibcxx_requires_nonempty();
23838fd1498Szrj 	return c.back();
23938fd1498Szrj       }
24038fd1498Szrj 
24138fd1498Szrj       /**
24238fd1498Szrj        *  @brief  Add data to the end of the %queue.
24338fd1498Szrj        *  @param  __x  Data to be added.
24438fd1498Szrj        *
24538fd1498Szrj        *  This is a typical %queue operation.  The function creates an
24638fd1498Szrj        *  element at the end of the %queue and assigns the given data
24738fd1498Szrj        *  to it.  The time complexity of the operation depends on the
24838fd1498Szrj        *  underlying sequence.
24938fd1498Szrj        */
25038fd1498Szrj       void
25138fd1498Szrj       push(const value_type& __x)
25238fd1498Szrj       { c.push_back(__x); }
25338fd1498Szrj 
25438fd1498Szrj #if __cplusplus >= 201103L
25538fd1498Szrj       void
25638fd1498Szrj       push(value_type&& __x)
25738fd1498Szrj       { c.push_back(std::move(__x)); }
25838fd1498Szrj 
25938fd1498Szrj #if __cplusplus > 201402L
26038fd1498Szrj       template<typename... _Args>
26138fd1498Szrj 	decltype(auto)
26238fd1498Szrj 	emplace(_Args&&... __args)
26338fd1498Szrj 	{ return c.emplace_back(std::forward<_Args>(__args)...); }
26438fd1498Szrj #else
26538fd1498Szrj       template<typename... _Args>
26638fd1498Szrj 	void
26738fd1498Szrj 	emplace(_Args&&... __args)
26838fd1498Szrj 	{ c.emplace_back(std::forward<_Args>(__args)...); }
26938fd1498Szrj #endif
27038fd1498Szrj #endif
27138fd1498Szrj 
27238fd1498Szrj       /**
27338fd1498Szrj        *  @brief  Removes first element.
27438fd1498Szrj        *
27538fd1498Szrj        *  This is a typical %queue operation.  It shrinks the %queue by one.
27638fd1498Szrj        *  The time complexity of the operation depends on the underlying
27738fd1498Szrj        *  sequence.
27838fd1498Szrj        *
27938fd1498Szrj        *  Note that no data is returned, and if the first element's
28038fd1498Szrj        *  data is needed, it should be retrieved before pop() is
28138fd1498Szrj        *  called.
28238fd1498Szrj        */
28338fd1498Szrj       void
28438fd1498Szrj       pop()
28538fd1498Szrj       {
28638fd1498Szrj 	__glibcxx_requires_nonempty();
28738fd1498Szrj 	c.pop_front();
28838fd1498Szrj       }
28938fd1498Szrj 
29038fd1498Szrj #if __cplusplus >= 201103L
29138fd1498Szrj       void
29238fd1498Szrj       swap(queue& __q)
29338fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
29438fd1498Szrj       noexcept(__is_nothrow_swappable<_Sequence>::value)
29538fd1498Szrj #else
29638fd1498Szrj       noexcept(__is_nothrow_swappable<_Tp>::value)
29738fd1498Szrj #endif
29838fd1498Szrj       {
29938fd1498Szrj 	using std::swap;
30038fd1498Szrj 	swap(c, __q.c);
30138fd1498Szrj       }
30238fd1498Szrj #endif // __cplusplus >= 201103L
30338fd1498Szrj     };
30438fd1498Szrj 
305*58e805e6Szrj #if __cpp_deduction_guides >= 201606
306*58e805e6Szrj   template<typename _Container,
307*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Container>::value>>
308*58e805e6Szrj     queue(_Container) -> queue<typename _Container::value_type, _Container>;
309*58e805e6Szrj 
310*58e805e6Szrj   template<typename _Container, typename _Allocator,
311*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Container>::value>,
312*58e805e6Szrj 	   typename = enable_if_t<__is_allocator<_Allocator>::value>>
313*58e805e6Szrj     queue(_Container, _Allocator)
314*58e805e6Szrj     -> queue<typename _Container::value_type, _Container>;
315*58e805e6Szrj #endif
316*58e805e6Szrj 
31738fd1498Szrj   /**
31838fd1498Szrj    *  @brief  Queue equality comparison.
31938fd1498Szrj    *  @param  __x  A %queue.
32038fd1498Szrj    *  @param  __y  A %queue of the same type as @a __x.
32138fd1498Szrj    *  @return  True iff the size and elements of the queues are equal.
32238fd1498Szrj    *
32338fd1498Szrj    *  This is an equivalence relation.  Complexity and semantics depend on the
32438fd1498Szrj    *  underlying sequence type, but the expected rules are:  this relation is
32538fd1498Szrj    *  linear in the size of the sequences, and queues are considered equivalent
32638fd1498Szrj    *  if their sequences compare equal.
32738fd1498Szrj   */
32838fd1498Szrj   template<typename _Tp, typename _Seq>
32938fd1498Szrj     inline bool
33038fd1498Szrj     operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
33138fd1498Szrj     { return __x.c == __y.c; }
33238fd1498Szrj 
33338fd1498Szrj   /**
33438fd1498Szrj    *  @brief  Queue ordering relation.
33538fd1498Szrj    *  @param  __x  A %queue.
33638fd1498Szrj    *  @param  __y  A %queue of the same type as @a x.
33738fd1498Szrj    *  @return  True iff @a __x is lexicographically less than @a __y.
33838fd1498Szrj    *
33938fd1498Szrj    *  This is an total ordering relation.  Complexity and semantics
34038fd1498Szrj    *  depend on the underlying sequence type, but the expected rules
34138fd1498Szrj    *  are: this relation is linear in the size of the sequences, the
34238fd1498Szrj    *  elements must be comparable with @c <, and
34338fd1498Szrj    *  std::lexicographical_compare() is usually used to make the
34438fd1498Szrj    *  determination.
34538fd1498Szrj   */
34638fd1498Szrj   template<typename _Tp, typename _Seq>
34738fd1498Szrj     inline bool
34838fd1498Szrj     operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
34938fd1498Szrj     { return __x.c < __y.c; }
35038fd1498Szrj 
35138fd1498Szrj   /// Based on operator==
35238fd1498Szrj   template<typename _Tp, typename _Seq>
35338fd1498Szrj     inline bool
35438fd1498Szrj     operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
35538fd1498Szrj     { return !(__x == __y); }
35638fd1498Szrj 
35738fd1498Szrj   /// Based on operator<
35838fd1498Szrj   template<typename _Tp, typename _Seq>
35938fd1498Szrj     inline bool
36038fd1498Szrj     operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
36138fd1498Szrj     { return __y < __x; }
36238fd1498Szrj 
36338fd1498Szrj   /// Based on operator<
36438fd1498Szrj   template<typename _Tp, typename _Seq>
36538fd1498Szrj     inline bool
36638fd1498Szrj     operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
36738fd1498Szrj     { return !(__y < __x); }
36838fd1498Szrj 
36938fd1498Szrj   /// Based on operator<
37038fd1498Szrj   template<typename _Tp, typename _Seq>
37138fd1498Szrj     inline bool
37238fd1498Szrj     operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
37338fd1498Szrj     { return !(__x < __y); }
37438fd1498Szrj 
37538fd1498Szrj #if __cplusplus >= 201103L
37638fd1498Szrj   template<typename _Tp, typename _Seq>
37738fd1498Szrj     inline
37838fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
37938fd1498Szrj     // Constrained free swap overload, see p0185r1
38038fd1498Szrj     typename enable_if<__is_swappable<_Seq>::value>::type
38138fd1498Szrj #else
38238fd1498Szrj     void
38338fd1498Szrj #endif
38438fd1498Szrj     swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
38538fd1498Szrj     noexcept(noexcept(__x.swap(__y)))
38638fd1498Szrj     { __x.swap(__y); }
38738fd1498Szrj 
38838fd1498Szrj   template<typename _Tp, typename _Seq, typename _Alloc>
38938fd1498Szrj     struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
39038fd1498Szrj     : public uses_allocator<_Seq, _Alloc>::type { };
39138fd1498Szrj #endif // __cplusplus >= 201103L
39238fd1498Szrj 
39338fd1498Szrj   /**
39438fd1498Szrj    *  @brief  A standard container automatically sorting its contents.
39538fd1498Szrj    *
39638fd1498Szrj    *  @ingroup sequences
39738fd1498Szrj    *
39838fd1498Szrj    *  @tparam _Tp  Type of element.
39938fd1498Szrj    *  @tparam _Sequence  Type of underlying sequence, defaults to vector<_Tp>.
40038fd1498Szrj    *  @tparam _Compare  Comparison function object type, defaults to
40138fd1498Szrj    *                    less<_Sequence::value_type>.
40238fd1498Szrj    *
40338fd1498Szrj    *  This is not a true container, but an @e adaptor.  It holds
40438fd1498Szrj    *  another container, and provides a wrapper interface to that
40538fd1498Szrj    *  container.  The wrapper is what enforces priority-based sorting
40638fd1498Szrj    *  and %queue behavior.  Very few of the standard container/sequence
40738fd1498Szrj    *  interface requirements are met (e.g., iterators).
40838fd1498Szrj    *
40938fd1498Szrj    *  The second template parameter defines the type of the underlying
41038fd1498Szrj    *  sequence/container.  It defaults to std::vector, but it can be
41138fd1498Szrj    *  any type that supports @c front(), @c push_back, @c pop_back,
41238fd1498Szrj    *  and random-access iterators, such as std::deque or an
41338fd1498Szrj    *  appropriate user-defined type.
41438fd1498Szrj    *
41538fd1498Szrj    *  The third template parameter supplies the means of making
41638fd1498Szrj    *  priority comparisons.  It defaults to @c less<value_type> but
41738fd1498Szrj    *  can be anything defining a strict weak ordering.
41838fd1498Szrj    *
41938fd1498Szrj    *  Members not found in @a normal containers are @c container_type,
42038fd1498Szrj    *  which is a typedef for the second Sequence parameter, and @c
42138fd1498Szrj    *  push, @c pop, and @c top, which are standard %queue operations.
42238fd1498Szrj    *
42338fd1498Szrj    *  @note No equality/comparison operators are provided for
42438fd1498Szrj    *  %priority_queue.
42538fd1498Szrj    *
42638fd1498Szrj    *  @note Sorting of the elements takes place as they are added to,
42738fd1498Szrj    *  and removed from, the %priority_queue using the
42838fd1498Szrj    *  %priority_queue's member functions.  If you access the elements
42938fd1498Szrj    *  by other means, and change their data such that the sorting
43038fd1498Szrj    *  order would be different, the %priority_queue will not re-sort
43138fd1498Szrj    *  the elements for you.  (How could it know to do so?)
43238fd1498Szrj   */
43338fd1498Szrj   template<typename _Tp, typename _Sequence = vector<_Tp>,
43438fd1498Szrj 	   typename _Compare  = less<typename _Sequence::value_type> >
43538fd1498Szrj     class priority_queue
43638fd1498Szrj     {
43738fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS
43838fd1498Szrj       // concept requirements
43938fd1498Szrj       typedef typename _Sequence::value_type _Sequence_value_type;
44038fd1498Szrj # if __cplusplus < 201103L
44138fd1498Szrj       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
44238fd1498Szrj # endif
44338fd1498Szrj       __glibcxx_class_requires(_Sequence, _SequenceConcept)
44438fd1498Szrj       __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
44538fd1498Szrj       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
44638fd1498Szrj       __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
44738fd1498Szrj 				_BinaryFunctionConcept)
44838fd1498Szrj #endif
44938fd1498Szrj 
45038fd1498Szrj #if __cplusplus >= 201103L
45138fd1498Szrj       template<typename _Alloc>
45238fd1498Szrj 	using _Uses = typename
45338fd1498Szrj 	  enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
45438fd1498Szrj #endif
45538fd1498Szrj 
45638fd1498Szrj     public:
45738fd1498Szrj       typedef typename	_Sequence::value_type		value_type;
45838fd1498Szrj       typedef typename	_Sequence::reference		 reference;
45938fd1498Szrj       typedef typename	_Sequence::const_reference	   const_reference;
46038fd1498Szrj       typedef typename	_Sequence::size_type		 size_type;
46138fd1498Szrj       typedef		_Sequence			    container_type;
46238fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
46338fd1498Szrj       // DR 2684. priority_queue lacking comparator typedef
46438fd1498Szrj       typedef	       _Compare				    value_compare;
46538fd1498Szrj 
46638fd1498Szrj     protected:
46738fd1498Szrj       //  See queue::c for notes on these names.
46838fd1498Szrj       _Sequence  c;
46938fd1498Szrj       _Compare   comp;
47038fd1498Szrj 
47138fd1498Szrj     public:
47238fd1498Szrj       /**
47338fd1498Szrj        *  @brief  Default constructor creates no elements.
47438fd1498Szrj        */
47538fd1498Szrj #if __cplusplus < 201103L
47638fd1498Szrj       explicit
47738fd1498Szrj       priority_queue(const _Compare& __x = _Compare(),
47838fd1498Szrj 		     const _Sequence& __s = _Sequence())
47938fd1498Szrj       : c(__s), comp(__x)
48038fd1498Szrj       { std::make_heap(c.begin(), c.end(), comp); }
48138fd1498Szrj #else
48238fd1498Szrj       template<typename _Seq = _Sequence, typename _Requires = typename
48338fd1498Szrj 	       enable_if<__and_<is_default_constructible<_Compare>,
48438fd1498Szrj 				is_default_constructible<_Seq>>::value>::type>
48538fd1498Szrj 	priority_queue()
48638fd1498Szrj 	: c(), comp() { }
48738fd1498Szrj 
48838fd1498Szrj       explicit
48938fd1498Szrj       priority_queue(const _Compare& __x, const _Sequence& __s)
49038fd1498Szrj       : c(__s), comp(__x)
49138fd1498Szrj       { std::make_heap(c.begin(), c.end(), comp); }
49238fd1498Szrj 
49338fd1498Szrj       explicit
49438fd1498Szrj       priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence())
49538fd1498Szrj       : c(std::move(__s)), comp(__x)
49638fd1498Szrj       { std::make_heap(c.begin(), c.end(), comp); }
49738fd1498Szrj 
49838fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
49938fd1498Szrj 	explicit
50038fd1498Szrj 	priority_queue(const _Alloc& __a)
50138fd1498Szrj 	: c(__a), comp() { }
50238fd1498Szrj 
50338fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
50438fd1498Szrj 	priority_queue(const _Compare& __x, const _Alloc& __a)
50538fd1498Szrj 	: c(__a), comp(__x) { }
50638fd1498Szrj 
50738fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
50838fd1498Szrj 	priority_queue(const _Compare& __x, const _Sequence& __c,
50938fd1498Szrj 		       const _Alloc& __a)
51038fd1498Szrj 	: c(__c, __a), comp(__x) { }
51138fd1498Szrj 
51238fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
51338fd1498Szrj 	priority_queue(const _Compare& __x, _Sequence&& __c, const _Alloc& __a)
51438fd1498Szrj 	: c(std::move(__c), __a), comp(__x) { }
51538fd1498Szrj 
51638fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
51738fd1498Szrj 	priority_queue(const priority_queue& __q, const _Alloc& __a)
51838fd1498Szrj 	: c(__q.c, __a), comp(__q.comp) { }
51938fd1498Szrj 
52038fd1498Szrj       template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
52138fd1498Szrj 	priority_queue(priority_queue&& __q, const _Alloc& __a)
52238fd1498Szrj 	: c(std::move(__q.c), __a), comp(std::move(__q.comp)) { }
52338fd1498Szrj #endif
52438fd1498Szrj 
52538fd1498Szrj       /**
52638fd1498Szrj        *  @brief  Builds a %queue from a range.
52738fd1498Szrj        *  @param  __first  An input iterator.
52838fd1498Szrj        *  @param  __last  An input iterator.
52938fd1498Szrj        *  @param  __x  A comparison functor describing a strict weak ordering.
53038fd1498Szrj        *  @param  __s  An initial sequence with which to start.
53138fd1498Szrj        *
53238fd1498Szrj        *  Begins by copying @a __s, inserting a copy of the elements
53338fd1498Szrj        *  from @a [first,last) into the copy of @a __s, then ordering
53438fd1498Szrj        *  the copy according to @a __x.
53538fd1498Szrj        *
53638fd1498Szrj        *  For more information on function objects, see the
53738fd1498Szrj        *  documentation on @link functors functor base
53838fd1498Szrj        *  classes@endlink.
53938fd1498Szrj        */
54038fd1498Szrj #if __cplusplus < 201103L
54138fd1498Szrj       template<typename _InputIterator>
54238fd1498Szrj 	priority_queue(_InputIterator __first, _InputIterator __last,
54338fd1498Szrj 		       const _Compare& __x = _Compare(),
54438fd1498Szrj 		       const _Sequence& __s = _Sequence())
54538fd1498Szrj 	: c(__s), comp(__x)
54638fd1498Szrj 	{
54738fd1498Szrj 	  __glibcxx_requires_valid_range(__first, __last);
54838fd1498Szrj 	  c.insert(c.end(), __first, __last);
54938fd1498Szrj 	  std::make_heap(c.begin(), c.end(), comp);
55038fd1498Szrj 	}
55138fd1498Szrj #else
55238fd1498Szrj       template<typename _InputIterator>
55338fd1498Szrj 	priority_queue(_InputIterator __first, _InputIterator __last,
55438fd1498Szrj 		       const _Compare& __x,
55538fd1498Szrj 		       const _Sequence& __s)
55638fd1498Szrj 	: c(__s), comp(__x)
55738fd1498Szrj 	{
55838fd1498Szrj 	  __glibcxx_requires_valid_range(__first, __last);
55938fd1498Szrj 	  c.insert(c.end(), __first, __last);
56038fd1498Szrj 	  std::make_heap(c.begin(), c.end(), comp);
56138fd1498Szrj 	}
56238fd1498Szrj 
56338fd1498Szrj       template<typename _InputIterator>
56438fd1498Szrj 	priority_queue(_InputIterator __first, _InputIterator __last,
56538fd1498Szrj 		       const _Compare& __x = _Compare(),
56638fd1498Szrj 		       _Sequence&& __s = _Sequence())
56738fd1498Szrj 	: c(std::move(__s)), comp(__x)
56838fd1498Szrj 	{
56938fd1498Szrj 	  __glibcxx_requires_valid_range(__first, __last);
57038fd1498Szrj 	  c.insert(c.end(), __first, __last);
57138fd1498Szrj 	  std::make_heap(c.begin(), c.end(), comp);
57238fd1498Szrj 	}
57338fd1498Szrj #endif
57438fd1498Szrj 
57538fd1498Szrj       /**
57638fd1498Szrj        *  Returns true if the %queue is empty.
57738fd1498Szrj        */
57838fd1498Szrj       bool
57938fd1498Szrj       empty() const
58038fd1498Szrj       { return c.empty(); }
58138fd1498Szrj 
58238fd1498Szrj       /**  Returns the number of elements in the %queue.  */
58338fd1498Szrj       size_type
58438fd1498Szrj       size() const
58538fd1498Szrj       { return c.size(); }
58638fd1498Szrj 
58738fd1498Szrj       /**
58838fd1498Szrj        *  Returns a read-only (constant) reference to the data at the first
58938fd1498Szrj        *  element of the %queue.
59038fd1498Szrj        */
59138fd1498Szrj       const_reference
59238fd1498Szrj       top() const
59338fd1498Szrj       {
59438fd1498Szrj 	__glibcxx_requires_nonempty();
59538fd1498Szrj 	return c.front();
59638fd1498Szrj       }
59738fd1498Szrj 
59838fd1498Szrj       /**
59938fd1498Szrj        *  @brief  Add data to the %queue.
60038fd1498Szrj        *  @param  __x  Data to be added.
60138fd1498Szrj        *
60238fd1498Szrj        *  This is a typical %queue operation.
60338fd1498Szrj        *  The time complexity of the operation depends on the underlying
60438fd1498Szrj        *  sequence.
60538fd1498Szrj        */
60638fd1498Szrj       void
60738fd1498Szrj       push(const value_type& __x)
60838fd1498Szrj       {
60938fd1498Szrj 	c.push_back(__x);
61038fd1498Szrj 	std::push_heap(c.begin(), c.end(), comp);
61138fd1498Szrj       }
61238fd1498Szrj 
61338fd1498Szrj #if __cplusplus >= 201103L
61438fd1498Szrj       void
61538fd1498Szrj       push(value_type&& __x)
61638fd1498Szrj       {
61738fd1498Szrj 	c.push_back(std::move(__x));
61838fd1498Szrj 	std::push_heap(c.begin(), c.end(), comp);
61938fd1498Szrj       }
62038fd1498Szrj 
62138fd1498Szrj       template<typename... _Args>
62238fd1498Szrj 	void
62338fd1498Szrj 	emplace(_Args&&... __args)
62438fd1498Szrj 	{
62538fd1498Szrj 	  c.emplace_back(std::forward<_Args>(__args)...);
62638fd1498Szrj 	  std::push_heap(c.begin(), c.end(), comp);
62738fd1498Szrj 	}
62838fd1498Szrj #endif
62938fd1498Szrj 
63038fd1498Szrj       /**
63138fd1498Szrj        *  @brief  Removes first element.
63238fd1498Szrj        *
63338fd1498Szrj        *  This is a typical %queue operation.  It shrinks the %queue
63438fd1498Szrj        *  by one.  The time complexity of the operation depends on the
63538fd1498Szrj        *  underlying sequence.
63638fd1498Szrj        *
63738fd1498Szrj        *  Note that no data is returned, and if the first element's
63838fd1498Szrj        *  data is needed, it should be retrieved before pop() is
63938fd1498Szrj        *  called.
64038fd1498Szrj        */
64138fd1498Szrj       void
64238fd1498Szrj       pop()
64338fd1498Szrj       {
64438fd1498Szrj 	__glibcxx_requires_nonempty();
64538fd1498Szrj 	std::pop_heap(c.begin(), c.end(), comp);
64638fd1498Szrj 	c.pop_back();
64738fd1498Szrj       }
64838fd1498Szrj 
64938fd1498Szrj #if __cplusplus >= 201103L
65038fd1498Szrj       void
65138fd1498Szrj       swap(priority_queue& __pq)
65238fd1498Szrj       noexcept(__and_<
65338fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
65438fd1498Szrj 		 __is_nothrow_swappable<_Sequence>,
65538fd1498Szrj #else
65638fd1498Szrj 		 __is_nothrow_swappable<_Tp>,
65738fd1498Szrj #endif
65838fd1498Szrj 		 __is_nothrow_swappable<_Compare>
65938fd1498Szrj 	       >::value)
66038fd1498Szrj       {
66138fd1498Szrj 	using std::swap;
66238fd1498Szrj 	swap(c, __pq.c);
66338fd1498Szrj 	swap(comp, __pq.comp);
66438fd1498Szrj       }
66538fd1498Szrj #endif // __cplusplus >= 201103L
66638fd1498Szrj     };
66738fd1498Szrj 
668*58e805e6Szrj #if __cpp_deduction_guides >= 201606
669*58e805e6Szrj   template<typename _Compare, typename _Container,
670*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Compare>::value>,
671*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Container>::value>>
672*58e805e6Szrj     priority_queue(_Compare, _Container)
673*58e805e6Szrj     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
674*58e805e6Szrj 
675*58e805e6Szrj   template<typename _InputIterator, typename _ValT
676*58e805e6Szrj 	   = typename iterator_traits<_InputIterator>::value_type,
677*58e805e6Szrj 	   typename _Compare = less<_ValT>,
678*58e805e6Szrj 	   typename _Container = vector<_ValT>,
679*58e805e6Szrj 	   typename = _RequireInputIter<_InputIterator>,
680*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Compare>::value>,
681*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Container>::value>>
682*58e805e6Szrj     priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(),
683*58e805e6Szrj 		   _Container = _Container())
684*58e805e6Szrj     -> priority_queue<_ValT, _Container, _Compare>;
685*58e805e6Szrj 
686*58e805e6Szrj   template<typename _Compare, typename _Container, typename _Allocator,
687*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Compare>::value>,
688*58e805e6Szrj 	   typename = enable_if_t<!__is_allocator<_Container>::value>,
689*58e805e6Szrj 	   typename = enable_if_t<__is_allocator<_Allocator>::value>>
690*58e805e6Szrj     priority_queue(_Compare, _Container, _Allocator)
691*58e805e6Szrj     -> priority_queue<typename _Container::value_type, _Container, _Compare>;
692*58e805e6Szrj #endif
693*58e805e6Szrj 
69438fd1498Szrj   // No equality/comparison operators are provided for priority_queue.
69538fd1498Szrj 
69638fd1498Szrj #if __cplusplus >= 201103L
69738fd1498Szrj   template<typename _Tp, typename _Sequence, typename _Compare>
69838fd1498Szrj     inline
69938fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
70038fd1498Szrj     // Constrained free swap overload, see p0185r1
70138fd1498Szrj     typename enable_if<__and_<__is_swappable<_Sequence>,
70238fd1498Szrj 			      __is_swappable<_Compare>>::value>::type
70338fd1498Szrj #else
70438fd1498Szrj     void
70538fd1498Szrj #endif
70638fd1498Szrj     swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
70738fd1498Szrj 	 priority_queue<_Tp, _Sequence, _Compare>& __y)
70838fd1498Szrj     noexcept(noexcept(__x.swap(__y)))
70938fd1498Szrj     { __x.swap(__y); }
71038fd1498Szrj 
71138fd1498Szrj   template<typename _Tp, typename _Sequence, typename _Compare,
71238fd1498Szrj 	   typename _Alloc>
71338fd1498Szrj     struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
71438fd1498Szrj     : public uses_allocator<_Sequence, _Alloc>::type { };
71538fd1498Szrj #endif // __cplusplus >= 201103L
71638fd1498Szrj 
71738fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
71838fd1498Szrj } // namespace
71938fd1498Szrj 
72038fd1498Szrj #endif /* _STL_QUEUE_H */
721