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