11debfc3dSmrg // Queue implementation -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /*
261debfc3dSmrg *
271debfc3dSmrg * Copyright (c) 1994
281debfc3dSmrg * Hewlett-Packard Company
291debfc3dSmrg *
301debfc3dSmrg * Permission to use, copy, modify, distribute and sell this software
311debfc3dSmrg * and its documentation for any purpose is hereby granted without fee,
321debfc3dSmrg * provided that the above copyright notice appear in all copies and
331debfc3dSmrg * that both that copyright notice and this permission notice appear
341debfc3dSmrg * in supporting documentation. Hewlett-Packard Company makes no
351debfc3dSmrg * representations about the suitability of this software for any
361debfc3dSmrg * purpose. It is provided "as is" without express or implied warranty.
371debfc3dSmrg *
381debfc3dSmrg *
391debfc3dSmrg * Copyright (c) 1996,1997
401debfc3dSmrg * Silicon Graphics Computer Systems, Inc.
411debfc3dSmrg *
421debfc3dSmrg * Permission to use, copy, modify, distribute and sell this software
431debfc3dSmrg * and its documentation for any purpose is hereby granted without fee,
441debfc3dSmrg * provided that the above copyright notice appear in all copies and
451debfc3dSmrg * that both that copyright notice and this permission notice appear
461debfc3dSmrg * in supporting documentation. Silicon Graphics makes no
471debfc3dSmrg * representations about the suitability of this software for any
481debfc3dSmrg * purpose. It is provided "as is" without express or implied warranty.
491debfc3dSmrg */
501debfc3dSmrg
511debfc3dSmrg /** @file bits/stl_queue.h
521debfc3dSmrg * This is an internal header file, included by other library headers.
531debfc3dSmrg * Do not attempt to use it directly. @headername{queue}
541debfc3dSmrg */
551debfc3dSmrg
561debfc3dSmrg #ifndef _STL_QUEUE_H
571debfc3dSmrg #define _STL_QUEUE_H 1
581debfc3dSmrg
591debfc3dSmrg #include <bits/concept_check.h>
601debfc3dSmrg #include <debug/debug.h>
611debfc3dSmrg #if __cplusplus >= 201103L
621debfc3dSmrg # include <bits/uses_allocator.h>
631debfc3dSmrg #endif
641debfc3dSmrg
_GLIBCXX_VISIBILITY(default)651debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
661debfc3dSmrg {
671debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
681debfc3dSmrg
691debfc3dSmrg /**
701debfc3dSmrg * @brief A standard container giving FIFO behavior.
711debfc3dSmrg *
721debfc3dSmrg * @ingroup sequences
731debfc3dSmrg *
741debfc3dSmrg * @tparam _Tp Type of element.
751debfc3dSmrg * @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>.
761debfc3dSmrg *
771debfc3dSmrg * Meets many of the requirements of a
781debfc3dSmrg * <a href="tables.html#65">container</a>,
791debfc3dSmrg * but does not define anything to do with iterators. Very few of the
801debfc3dSmrg * other standard container interfaces are defined.
811debfc3dSmrg *
821debfc3dSmrg * This is not a true container, but an @e adaptor. It holds another
831debfc3dSmrg * container, and provides a wrapper interface to that container. The
841debfc3dSmrg * wrapper is what enforces strict first-in-first-out %queue behavior.
851debfc3dSmrg *
861debfc3dSmrg * The second template parameter defines the type of the underlying
871debfc3dSmrg * sequence/container. It defaults to std::deque, but it can be any type
881debfc3dSmrg * that supports @c front, @c back, @c push_back, and @c pop_front,
891debfc3dSmrg * such as std::list or an appropriate user-defined type.
901debfc3dSmrg *
911debfc3dSmrg * Members not found in @a normal containers are @c container_type,
921debfc3dSmrg * which is a typedef for the second Sequence parameter, and @c push and
931debfc3dSmrg * @c pop, which are standard %queue/FIFO operations.
941debfc3dSmrg */
951debfc3dSmrg template<typename _Tp, typename _Sequence = deque<_Tp> >
961debfc3dSmrg class queue
971debfc3dSmrg {
981debfc3dSmrg #ifdef _GLIBCXX_CONCEPT_CHECKS
991debfc3dSmrg // concept requirements
1001debfc3dSmrg typedef typename _Sequence::value_type _Sequence_value_type;
1011debfc3dSmrg # if __cplusplus < 201103L
1021debfc3dSmrg __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
1031debfc3dSmrg # endif
1041debfc3dSmrg __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
1051debfc3dSmrg __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
1061debfc3dSmrg __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
1071debfc3dSmrg #endif
1081debfc3dSmrg
1091debfc3dSmrg template<typename _Tp1, typename _Seq1>
1101debfc3dSmrg friend bool
1111debfc3dSmrg operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
1121debfc3dSmrg
1131debfc3dSmrg template<typename _Tp1, typename _Seq1>
1141debfc3dSmrg friend bool
1151debfc3dSmrg operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
1161debfc3dSmrg
117*8feb0f0bSmrg #if __cpp_lib_three_way_comparison
118*8feb0f0bSmrg template<typename _Tp1, three_way_comparable _Seq1>
119*8feb0f0bSmrg friend compare_three_way_result_t<_Seq1>
120*8feb0f0bSmrg operator<=>(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
121*8feb0f0bSmrg #endif
122*8feb0f0bSmrg
1231debfc3dSmrg #if __cplusplus >= 201103L
1241debfc3dSmrg template<typename _Alloc>
1251debfc3dSmrg using _Uses = typename
1261debfc3dSmrg enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
127c0a68be4Smrg
128c0a68be4Smrg #if __cplusplus >= 201703L
129c0a68be4Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
130c0a68be4Smrg // 2566. Requirements on the first template parameter of container
131c0a68be4Smrg // adaptors
132c0a68be4Smrg static_assert(is_same<_Tp, typename _Sequence::value_type>::value,
133c0a68be4Smrg "value_type must be the same as the underlying container");
134c0a68be4Smrg #endif // C++17
135c0a68be4Smrg #endif // C++11
1361debfc3dSmrg
1371debfc3dSmrg public:
1381debfc3dSmrg typedef typename _Sequence::value_type value_type;
1391debfc3dSmrg typedef typename _Sequence::reference reference;
1401debfc3dSmrg typedef typename _Sequence::const_reference const_reference;
1411debfc3dSmrg typedef typename _Sequence::size_type size_type;
1421debfc3dSmrg typedef _Sequence container_type;
1431debfc3dSmrg
1441debfc3dSmrg protected:
1451debfc3dSmrg /* Maintainers wondering why this isn't uglified as per style
1461debfc3dSmrg * guidelines should note that this name is specified in the standard,
1471debfc3dSmrg * C++98 [23.2.3.1].
1481debfc3dSmrg * (Why? Presumably for the same reason that it's protected instead
1491debfc3dSmrg * of private: to allow derivation. But none of the other
1501debfc3dSmrg * containers allow for derivation. Odd.)
1511debfc3dSmrg */
1521debfc3dSmrg /// @c c is the underlying container.
1531debfc3dSmrg _Sequence c;
1541debfc3dSmrg
1551debfc3dSmrg public:
1561debfc3dSmrg /**
1571debfc3dSmrg * @brief Default constructor creates no elements.
1581debfc3dSmrg */
1591debfc3dSmrg #if __cplusplus < 201103L
1601debfc3dSmrg explicit
1611debfc3dSmrg queue(const _Sequence& __c = _Sequence())
1621debfc3dSmrg : c(__c) { }
1631debfc3dSmrg #else
1641debfc3dSmrg template<typename _Seq = _Sequence, typename _Requires = typename
1651debfc3dSmrg enable_if<is_default_constructible<_Seq>::value>::type>
1661debfc3dSmrg queue()
1671debfc3dSmrg : c() { }
1681debfc3dSmrg
1691debfc3dSmrg explicit
1701debfc3dSmrg queue(const _Sequence& __c)
1711debfc3dSmrg : c(__c) { }
1721debfc3dSmrg
1731debfc3dSmrg explicit
1741debfc3dSmrg queue(_Sequence&& __c)
1751debfc3dSmrg : c(std::move(__c)) { }
1761debfc3dSmrg
1771debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
1781debfc3dSmrg explicit
1791debfc3dSmrg queue(const _Alloc& __a)
1801debfc3dSmrg : c(__a) { }
1811debfc3dSmrg
1821debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
1831debfc3dSmrg queue(const _Sequence& __c, const _Alloc& __a)
1841debfc3dSmrg : c(__c, __a) { }
1851debfc3dSmrg
1861debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
1871debfc3dSmrg queue(_Sequence&& __c, const _Alloc& __a)
1881debfc3dSmrg : c(std::move(__c), __a) { }
1891debfc3dSmrg
1901debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
1911debfc3dSmrg queue(const queue& __q, const _Alloc& __a)
1921debfc3dSmrg : c(__q.c, __a) { }
1931debfc3dSmrg
1941debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
1951debfc3dSmrg queue(queue&& __q, const _Alloc& __a)
1961debfc3dSmrg : c(std::move(__q.c), __a) { }
1971debfc3dSmrg #endif
1981debfc3dSmrg
1991debfc3dSmrg /**
2001debfc3dSmrg * Returns true if the %queue is empty.
2011debfc3dSmrg */
202c0a68be4Smrg _GLIBCXX_NODISCARD bool
2031debfc3dSmrg empty() const
2041debfc3dSmrg { return c.empty(); }
2051debfc3dSmrg
2061debfc3dSmrg /** Returns the number of elements in the %queue. */
2071debfc3dSmrg size_type
2081debfc3dSmrg size() const
2091debfc3dSmrg { return c.size(); }
2101debfc3dSmrg
2111debfc3dSmrg /**
2121debfc3dSmrg * Returns a read/write reference to the data at the first
2131debfc3dSmrg * element of the %queue.
2141debfc3dSmrg */
2151debfc3dSmrg reference
2161debfc3dSmrg front()
2171debfc3dSmrg {
2181debfc3dSmrg __glibcxx_requires_nonempty();
2191debfc3dSmrg return c.front();
2201debfc3dSmrg }
2211debfc3dSmrg
2221debfc3dSmrg /**
2231debfc3dSmrg * Returns a read-only (constant) reference to the data at the first
2241debfc3dSmrg * element of the %queue.
2251debfc3dSmrg */
2261debfc3dSmrg const_reference
2271debfc3dSmrg front() const
2281debfc3dSmrg {
2291debfc3dSmrg __glibcxx_requires_nonempty();
2301debfc3dSmrg return c.front();
2311debfc3dSmrg }
2321debfc3dSmrg
2331debfc3dSmrg /**
2341debfc3dSmrg * Returns a read/write reference to the data at the last
2351debfc3dSmrg * element of the %queue.
2361debfc3dSmrg */
2371debfc3dSmrg reference
2381debfc3dSmrg back()
2391debfc3dSmrg {
2401debfc3dSmrg __glibcxx_requires_nonempty();
2411debfc3dSmrg return c.back();
2421debfc3dSmrg }
2431debfc3dSmrg
2441debfc3dSmrg /**
2451debfc3dSmrg * Returns a read-only (constant) reference to the data at the last
2461debfc3dSmrg * element of the %queue.
2471debfc3dSmrg */
2481debfc3dSmrg const_reference
2491debfc3dSmrg back() const
2501debfc3dSmrg {
2511debfc3dSmrg __glibcxx_requires_nonempty();
2521debfc3dSmrg return c.back();
2531debfc3dSmrg }
2541debfc3dSmrg
2551debfc3dSmrg /**
2561debfc3dSmrg * @brief Add data to the end of the %queue.
2571debfc3dSmrg * @param __x Data to be added.
2581debfc3dSmrg *
2591debfc3dSmrg * This is a typical %queue operation. The function creates an
2601debfc3dSmrg * element at the end of the %queue and assigns the given data
2611debfc3dSmrg * to it. The time complexity of the operation depends on the
2621debfc3dSmrg * underlying sequence.
2631debfc3dSmrg */
2641debfc3dSmrg void
2651debfc3dSmrg push(const value_type& __x)
2661debfc3dSmrg { c.push_back(__x); }
2671debfc3dSmrg
2681debfc3dSmrg #if __cplusplus >= 201103L
2691debfc3dSmrg void
2701debfc3dSmrg push(value_type&& __x)
2711debfc3dSmrg { c.push_back(std::move(__x)); }
2721debfc3dSmrg
2731debfc3dSmrg #if __cplusplus > 201402L
2741debfc3dSmrg template<typename... _Args>
2751debfc3dSmrg decltype(auto)
2761debfc3dSmrg emplace(_Args&&... __args)
2771debfc3dSmrg { return c.emplace_back(std::forward<_Args>(__args)...); }
2781debfc3dSmrg #else
2791debfc3dSmrg template<typename... _Args>
2801debfc3dSmrg void
2811debfc3dSmrg emplace(_Args&&... __args)
2821debfc3dSmrg { c.emplace_back(std::forward<_Args>(__args)...); }
2831debfc3dSmrg #endif
2841debfc3dSmrg #endif
2851debfc3dSmrg
2861debfc3dSmrg /**
2871debfc3dSmrg * @brief Removes first element.
2881debfc3dSmrg *
2891debfc3dSmrg * This is a typical %queue operation. It shrinks the %queue by one.
2901debfc3dSmrg * The time complexity of the operation depends on the underlying
2911debfc3dSmrg * sequence.
2921debfc3dSmrg *
2931debfc3dSmrg * Note that no data is returned, and if the first element's
2941debfc3dSmrg * data is needed, it should be retrieved before pop() is
2951debfc3dSmrg * called.
2961debfc3dSmrg */
2971debfc3dSmrg void
2981debfc3dSmrg pop()
2991debfc3dSmrg {
3001debfc3dSmrg __glibcxx_requires_nonempty();
3011debfc3dSmrg c.pop_front();
3021debfc3dSmrg }
3031debfc3dSmrg
3041debfc3dSmrg #if __cplusplus >= 201103L
3051debfc3dSmrg void
3061debfc3dSmrg swap(queue& __q)
3071debfc3dSmrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
3081debfc3dSmrg noexcept(__is_nothrow_swappable<_Sequence>::value)
3091debfc3dSmrg #else
3101debfc3dSmrg noexcept(__is_nothrow_swappable<_Tp>::value)
3111debfc3dSmrg #endif
3121debfc3dSmrg {
3131debfc3dSmrg using std::swap;
3141debfc3dSmrg swap(c, __q.c);
3151debfc3dSmrg }
3161debfc3dSmrg #endif // __cplusplus >= 201103L
3171debfc3dSmrg };
3181debfc3dSmrg
319a2dc1f3fSmrg #if __cpp_deduction_guides >= 201606
320a2dc1f3fSmrg template<typename _Container,
321c0a68be4Smrg typename = _RequireNotAllocator<_Container>>
322a2dc1f3fSmrg queue(_Container) -> queue<typename _Container::value_type, _Container>;
323a2dc1f3fSmrg
324a2dc1f3fSmrg template<typename _Container, typename _Allocator,
325c0a68be4Smrg typename = _RequireNotAllocator<_Container>,
326c0a68be4Smrg typename = _RequireAllocator<_Allocator>>
327a2dc1f3fSmrg queue(_Container, _Allocator)
328a2dc1f3fSmrg -> queue<typename _Container::value_type, _Container>;
329a2dc1f3fSmrg #endif
330a2dc1f3fSmrg
3311debfc3dSmrg /**
3321debfc3dSmrg * @brief Queue equality comparison.
3331debfc3dSmrg * @param __x A %queue.
3341debfc3dSmrg * @param __y A %queue of the same type as @a __x.
3351debfc3dSmrg * @return True iff the size and elements of the queues are equal.
3361debfc3dSmrg *
3371debfc3dSmrg * This is an equivalence relation. Complexity and semantics depend on the
3381debfc3dSmrg * underlying sequence type, but the expected rules are: this relation is
3391debfc3dSmrg * linear in the size of the sequences, and queues are considered equivalent
3401debfc3dSmrg * if their sequences compare equal.
3411debfc3dSmrg */
3421debfc3dSmrg template<typename _Tp, typename _Seq>
3431debfc3dSmrg inline bool
3441debfc3dSmrg operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3451debfc3dSmrg { return __x.c == __y.c; }
3461debfc3dSmrg
3471debfc3dSmrg /**
3481debfc3dSmrg * @brief Queue ordering relation.
3491debfc3dSmrg * @param __x A %queue.
3501debfc3dSmrg * @param __y A %queue of the same type as @a x.
3511debfc3dSmrg * @return True iff @a __x is lexicographically less than @a __y.
3521debfc3dSmrg *
3531debfc3dSmrg * This is an total ordering relation. Complexity and semantics
3541debfc3dSmrg * depend on the underlying sequence type, but the expected rules
3551debfc3dSmrg * are: this relation is linear in the size of the sequences, the
3561debfc3dSmrg * elements must be comparable with @c <, and
3571debfc3dSmrg * std::lexicographical_compare() is usually used to make the
3581debfc3dSmrg * determination.
3591debfc3dSmrg */
3601debfc3dSmrg template<typename _Tp, typename _Seq>
3611debfc3dSmrg inline bool
3621debfc3dSmrg operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3631debfc3dSmrg { return __x.c < __y.c; }
3641debfc3dSmrg
3651debfc3dSmrg /// Based on operator==
3661debfc3dSmrg template<typename _Tp, typename _Seq>
3671debfc3dSmrg inline bool
3681debfc3dSmrg operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3691debfc3dSmrg { return !(__x == __y); }
3701debfc3dSmrg
3711debfc3dSmrg /// Based on operator<
3721debfc3dSmrg template<typename _Tp, typename _Seq>
3731debfc3dSmrg inline bool
3741debfc3dSmrg operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3751debfc3dSmrg { return __y < __x; }
3761debfc3dSmrg
3771debfc3dSmrg /// Based on operator<
3781debfc3dSmrg template<typename _Tp, typename _Seq>
3791debfc3dSmrg inline bool
3801debfc3dSmrg operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3811debfc3dSmrg { return !(__y < __x); }
3821debfc3dSmrg
3831debfc3dSmrg /// Based on operator<
3841debfc3dSmrg template<typename _Tp, typename _Seq>
3851debfc3dSmrg inline bool
3861debfc3dSmrg operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
3871debfc3dSmrg { return !(__x < __y); }
3881debfc3dSmrg
389*8feb0f0bSmrg #if __cpp_lib_three_way_comparison
390*8feb0f0bSmrg template<typename _Tp, three_way_comparable _Seq>
391*8feb0f0bSmrg inline compare_three_way_result_t<_Seq>
392*8feb0f0bSmrg operator<=>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
393*8feb0f0bSmrg { return __x.c <=> __y.c; }
394*8feb0f0bSmrg #endif
395*8feb0f0bSmrg
3961debfc3dSmrg #if __cplusplus >= 201103L
3971debfc3dSmrg template<typename _Tp, typename _Seq>
3981debfc3dSmrg inline
3991debfc3dSmrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
4001debfc3dSmrg // Constrained free swap overload, see p0185r1
4011debfc3dSmrg typename enable_if<__is_swappable<_Seq>::value>::type
4021debfc3dSmrg #else
4031debfc3dSmrg void
4041debfc3dSmrg #endif
4051debfc3dSmrg swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
4061debfc3dSmrg noexcept(noexcept(__x.swap(__y)))
4071debfc3dSmrg { __x.swap(__y); }
4081debfc3dSmrg
4091debfc3dSmrg template<typename _Tp, typename _Seq, typename _Alloc>
4101debfc3dSmrg struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
4111debfc3dSmrg : public uses_allocator<_Seq, _Alloc>::type { };
4121debfc3dSmrg #endif // __cplusplus >= 201103L
4131debfc3dSmrg
4141debfc3dSmrg /**
4151debfc3dSmrg * @brief A standard container automatically sorting its contents.
4161debfc3dSmrg *
4171debfc3dSmrg * @ingroup sequences
4181debfc3dSmrg *
4191debfc3dSmrg * @tparam _Tp Type of element.
4201debfc3dSmrg * @tparam _Sequence Type of underlying sequence, defaults to vector<_Tp>.
4211debfc3dSmrg * @tparam _Compare Comparison function object type, defaults to
4221debfc3dSmrg * less<_Sequence::value_type>.
4231debfc3dSmrg *
4241debfc3dSmrg * This is not a true container, but an @e adaptor. It holds
4251debfc3dSmrg * another container, and provides a wrapper interface to that
4261debfc3dSmrg * container. The wrapper is what enforces priority-based sorting
4271debfc3dSmrg * and %queue behavior. Very few of the standard container/sequence
4281debfc3dSmrg * interface requirements are met (e.g., iterators).
4291debfc3dSmrg *
4301debfc3dSmrg * The second template parameter defines the type of the underlying
4311debfc3dSmrg * sequence/container. It defaults to std::vector, but it can be
4321debfc3dSmrg * any type that supports @c front(), @c push_back, @c pop_back,
4331debfc3dSmrg * and random-access iterators, such as std::deque or an
4341debfc3dSmrg * appropriate user-defined type.
4351debfc3dSmrg *
4361debfc3dSmrg * The third template parameter supplies the means of making
4371debfc3dSmrg * priority comparisons. It defaults to @c less<value_type> but
4381debfc3dSmrg * can be anything defining a strict weak ordering.
4391debfc3dSmrg *
4401debfc3dSmrg * Members not found in @a normal containers are @c container_type,
4411debfc3dSmrg * which is a typedef for the second Sequence parameter, and @c
4421debfc3dSmrg * push, @c pop, and @c top, which are standard %queue operations.
4431debfc3dSmrg *
4441debfc3dSmrg * @note No equality/comparison operators are provided for
4451debfc3dSmrg * %priority_queue.
4461debfc3dSmrg *
4471debfc3dSmrg * @note Sorting of the elements takes place as they are added to,
4481debfc3dSmrg * and removed from, the %priority_queue using the
4491debfc3dSmrg * %priority_queue's member functions. If you access the elements
4501debfc3dSmrg * by other means, and change their data such that the sorting
4511debfc3dSmrg * order would be different, the %priority_queue will not re-sort
4521debfc3dSmrg * the elements for you. (How could it know to do so?)
4531debfc3dSmrg */
4541debfc3dSmrg template<typename _Tp, typename _Sequence = vector<_Tp>,
4551debfc3dSmrg typename _Compare = less<typename _Sequence::value_type> >
4561debfc3dSmrg class priority_queue
4571debfc3dSmrg {
4581debfc3dSmrg #ifdef _GLIBCXX_CONCEPT_CHECKS
4591debfc3dSmrg // concept requirements
4601debfc3dSmrg typedef typename _Sequence::value_type _Sequence_value_type;
4611debfc3dSmrg # if __cplusplus < 201103L
4621debfc3dSmrg __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
4631debfc3dSmrg # endif
4641debfc3dSmrg __glibcxx_class_requires(_Sequence, _SequenceConcept)
4651debfc3dSmrg __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
4661debfc3dSmrg __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
4671debfc3dSmrg __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
4681debfc3dSmrg _BinaryFunctionConcept)
4691debfc3dSmrg #endif
4701debfc3dSmrg
4711debfc3dSmrg #if __cplusplus >= 201103L
4721debfc3dSmrg template<typename _Alloc>
4731debfc3dSmrg using _Uses = typename
4741debfc3dSmrg enable_if<uses_allocator<_Sequence, _Alloc>::value>::type;
475c0a68be4Smrg
476c0a68be4Smrg #if __cplusplus >= 201703L
477c0a68be4Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
478c0a68be4Smrg // 2566. Requirements on the first template parameter of container
479c0a68be4Smrg // adaptors
480c0a68be4Smrg static_assert(is_same<_Tp, typename _Sequence::value_type>::value,
481c0a68be4Smrg "value_type must be the same as the underlying container");
482c0a68be4Smrg #endif // C++17
483c0a68be4Smrg #endif // C++11
4841debfc3dSmrg
4851debfc3dSmrg public:
4861debfc3dSmrg typedef typename _Sequence::value_type value_type;
4871debfc3dSmrg typedef typename _Sequence::reference reference;
4881debfc3dSmrg typedef typename _Sequence::const_reference const_reference;
4891debfc3dSmrg typedef typename _Sequence::size_type size_type;
4901debfc3dSmrg typedef _Sequence container_type;
4911debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
4921debfc3dSmrg // DR 2684. priority_queue lacking comparator typedef
4931debfc3dSmrg typedef _Compare value_compare;
4941debfc3dSmrg
4951debfc3dSmrg protected:
4961debfc3dSmrg // See queue::c for notes on these names.
4971debfc3dSmrg _Sequence c;
4981debfc3dSmrg _Compare comp;
4991debfc3dSmrg
5001debfc3dSmrg public:
5011debfc3dSmrg /**
5021debfc3dSmrg * @brief Default constructor creates no elements.
5031debfc3dSmrg */
5041debfc3dSmrg #if __cplusplus < 201103L
5051debfc3dSmrg explicit
5061debfc3dSmrg priority_queue(const _Compare& __x = _Compare(),
5071debfc3dSmrg const _Sequence& __s = _Sequence())
5081debfc3dSmrg : c(__s), comp(__x)
5091debfc3dSmrg { std::make_heap(c.begin(), c.end(), comp); }
5101debfc3dSmrg #else
5111debfc3dSmrg template<typename _Seq = _Sequence, typename _Requires = typename
5121debfc3dSmrg enable_if<__and_<is_default_constructible<_Compare>,
5131debfc3dSmrg is_default_constructible<_Seq>>::value>::type>
5141debfc3dSmrg priority_queue()
5151debfc3dSmrg : c(), comp() { }
5161debfc3dSmrg
5171debfc3dSmrg explicit
5181debfc3dSmrg priority_queue(const _Compare& __x, const _Sequence& __s)
5191debfc3dSmrg : c(__s), comp(__x)
5201debfc3dSmrg { std::make_heap(c.begin(), c.end(), comp); }
5211debfc3dSmrg
5221debfc3dSmrg explicit
5231debfc3dSmrg priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence())
5241debfc3dSmrg : c(std::move(__s)), comp(__x)
5251debfc3dSmrg { std::make_heap(c.begin(), c.end(), comp); }
5261debfc3dSmrg
5271debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5281debfc3dSmrg explicit
5291debfc3dSmrg priority_queue(const _Alloc& __a)
5301debfc3dSmrg : c(__a), comp() { }
5311debfc3dSmrg
5321debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5331debfc3dSmrg priority_queue(const _Compare& __x, const _Alloc& __a)
5341debfc3dSmrg : c(__a), comp(__x) { }
5351debfc3dSmrg
536a2dc1f3fSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
537a2dc1f3fSmrg // 2537. Constructors [...] taking allocators should call make_heap
5381debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5391debfc3dSmrg priority_queue(const _Compare& __x, const _Sequence& __c,
5401debfc3dSmrg const _Alloc& __a)
541a2dc1f3fSmrg : c(__c, __a), comp(__x)
542a2dc1f3fSmrg { std::make_heap(c.begin(), c.end(), comp); }
5431debfc3dSmrg
5441debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5451debfc3dSmrg priority_queue(const _Compare& __x, _Sequence&& __c, const _Alloc& __a)
546a2dc1f3fSmrg : c(std::move(__c), __a), comp(__x)
547a2dc1f3fSmrg { std::make_heap(c.begin(), c.end(), comp); }
5481debfc3dSmrg
5491debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5501debfc3dSmrg priority_queue(const priority_queue& __q, const _Alloc& __a)
5511debfc3dSmrg : c(__q.c, __a), comp(__q.comp) { }
5521debfc3dSmrg
5531debfc3dSmrg template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
5541debfc3dSmrg priority_queue(priority_queue&& __q, const _Alloc& __a)
5551debfc3dSmrg : c(std::move(__q.c), __a), comp(std::move(__q.comp)) { }
5561debfc3dSmrg #endif
5571debfc3dSmrg
5581debfc3dSmrg /**
5591debfc3dSmrg * @brief Builds a %queue from a range.
5601debfc3dSmrg * @param __first An input iterator.
5611debfc3dSmrg * @param __last An input iterator.
5621debfc3dSmrg * @param __x A comparison functor describing a strict weak ordering.
5631debfc3dSmrg * @param __s An initial sequence with which to start.
5641debfc3dSmrg *
5651debfc3dSmrg * Begins by copying @a __s, inserting a copy of the elements
5661debfc3dSmrg * from @a [first,last) into the copy of @a __s, then ordering
5671debfc3dSmrg * the copy according to @a __x.
5681debfc3dSmrg *
5691debfc3dSmrg * For more information on function objects, see the
5701debfc3dSmrg * documentation on @link functors functor base
5711debfc3dSmrg * classes@endlink.
5721debfc3dSmrg */
5731debfc3dSmrg #if __cplusplus < 201103L
5741debfc3dSmrg template<typename _InputIterator>
5751debfc3dSmrg priority_queue(_InputIterator __first, _InputIterator __last,
5761debfc3dSmrg const _Compare& __x = _Compare(),
5771debfc3dSmrg const _Sequence& __s = _Sequence())
5781debfc3dSmrg : c(__s), comp(__x)
5791debfc3dSmrg {
5801debfc3dSmrg __glibcxx_requires_valid_range(__first, __last);
5811debfc3dSmrg c.insert(c.end(), __first, __last);
5821debfc3dSmrg std::make_heap(c.begin(), c.end(), comp);
5831debfc3dSmrg }
5841debfc3dSmrg #else
5851debfc3dSmrg template<typename _InputIterator>
5861debfc3dSmrg priority_queue(_InputIterator __first, _InputIterator __last,
5871debfc3dSmrg const _Compare& __x,
5881debfc3dSmrg const _Sequence& __s)
5891debfc3dSmrg : c(__s), comp(__x)
5901debfc3dSmrg {
5911debfc3dSmrg __glibcxx_requires_valid_range(__first, __last);
5921debfc3dSmrg c.insert(c.end(), __first, __last);
5931debfc3dSmrg std::make_heap(c.begin(), c.end(), comp);
5941debfc3dSmrg }
5951debfc3dSmrg
5961debfc3dSmrg template<typename _InputIterator>
5971debfc3dSmrg priority_queue(_InputIterator __first, _InputIterator __last,
5981debfc3dSmrg const _Compare& __x = _Compare(),
5991debfc3dSmrg _Sequence&& __s = _Sequence())
6001debfc3dSmrg : c(std::move(__s)), comp(__x)
6011debfc3dSmrg {
6021debfc3dSmrg __glibcxx_requires_valid_range(__first, __last);
6031debfc3dSmrg c.insert(c.end(), __first, __last);
6041debfc3dSmrg std::make_heap(c.begin(), c.end(), comp);
6051debfc3dSmrg }
6061debfc3dSmrg #endif
6071debfc3dSmrg
6081debfc3dSmrg /**
6091debfc3dSmrg * Returns true if the %queue is empty.
6101debfc3dSmrg */
611c0a68be4Smrg _GLIBCXX_NODISCARD bool
6121debfc3dSmrg empty() const
6131debfc3dSmrg { return c.empty(); }
6141debfc3dSmrg
6151debfc3dSmrg /** Returns the number of elements in the %queue. */
6161debfc3dSmrg size_type
6171debfc3dSmrg size() const
6181debfc3dSmrg { return c.size(); }
6191debfc3dSmrg
6201debfc3dSmrg /**
6211debfc3dSmrg * Returns a read-only (constant) reference to the data at the first
6221debfc3dSmrg * element of the %queue.
6231debfc3dSmrg */
6241debfc3dSmrg const_reference
6251debfc3dSmrg top() const
6261debfc3dSmrg {
6271debfc3dSmrg __glibcxx_requires_nonempty();
6281debfc3dSmrg return c.front();
6291debfc3dSmrg }
6301debfc3dSmrg
6311debfc3dSmrg /**
6321debfc3dSmrg * @brief Add data to the %queue.
6331debfc3dSmrg * @param __x Data to be added.
6341debfc3dSmrg *
6351debfc3dSmrg * This is a typical %queue operation.
6361debfc3dSmrg * The time complexity of the operation depends on the underlying
6371debfc3dSmrg * sequence.
6381debfc3dSmrg */
6391debfc3dSmrg void
6401debfc3dSmrg push(const value_type& __x)
6411debfc3dSmrg {
6421debfc3dSmrg c.push_back(__x);
6431debfc3dSmrg std::push_heap(c.begin(), c.end(), comp);
6441debfc3dSmrg }
6451debfc3dSmrg
6461debfc3dSmrg #if __cplusplus >= 201103L
6471debfc3dSmrg void
6481debfc3dSmrg push(value_type&& __x)
6491debfc3dSmrg {
6501debfc3dSmrg c.push_back(std::move(__x));
6511debfc3dSmrg std::push_heap(c.begin(), c.end(), comp);
6521debfc3dSmrg }
6531debfc3dSmrg
6541debfc3dSmrg template<typename... _Args>
6551debfc3dSmrg void
6561debfc3dSmrg emplace(_Args&&... __args)
6571debfc3dSmrg {
6581debfc3dSmrg c.emplace_back(std::forward<_Args>(__args)...);
6591debfc3dSmrg std::push_heap(c.begin(), c.end(), comp);
6601debfc3dSmrg }
6611debfc3dSmrg #endif
6621debfc3dSmrg
6631debfc3dSmrg /**
6641debfc3dSmrg * @brief Removes first element.
6651debfc3dSmrg *
6661debfc3dSmrg * This is a typical %queue operation. It shrinks the %queue
6671debfc3dSmrg * by one. The time complexity of the operation depends on the
6681debfc3dSmrg * underlying sequence.
6691debfc3dSmrg *
6701debfc3dSmrg * Note that no data is returned, and if the first element's
6711debfc3dSmrg * data is needed, it should be retrieved before pop() is
6721debfc3dSmrg * called.
6731debfc3dSmrg */
6741debfc3dSmrg void
6751debfc3dSmrg pop()
6761debfc3dSmrg {
6771debfc3dSmrg __glibcxx_requires_nonempty();
6781debfc3dSmrg std::pop_heap(c.begin(), c.end(), comp);
6791debfc3dSmrg c.pop_back();
6801debfc3dSmrg }
6811debfc3dSmrg
6821debfc3dSmrg #if __cplusplus >= 201103L
6831debfc3dSmrg void
6841debfc3dSmrg swap(priority_queue& __pq)
6851debfc3dSmrg noexcept(__and_<
6861debfc3dSmrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
6871debfc3dSmrg __is_nothrow_swappable<_Sequence>,
6881debfc3dSmrg #else
6891debfc3dSmrg __is_nothrow_swappable<_Tp>,
6901debfc3dSmrg #endif
6911debfc3dSmrg __is_nothrow_swappable<_Compare>
6921debfc3dSmrg >::value)
6931debfc3dSmrg {
6941debfc3dSmrg using std::swap;
6951debfc3dSmrg swap(c, __pq.c);
6961debfc3dSmrg swap(comp, __pq.comp);
6971debfc3dSmrg }
6981debfc3dSmrg #endif // __cplusplus >= 201103L
6991debfc3dSmrg };
7001debfc3dSmrg
701a2dc1f3fSmrg #if __cpp_deduction_guides >= 201606
702a2dc1f3fSmrg template<typename _Compare, typename _Container,
703c0a68be4Smrg typename = _RequireNotAllocator<_Compare>,
704c0a68be4Smrg typename = _RequireNotAllocator<_Container>>
705a2dc1f3fSmrg priority_queue(_Compare, _Container)
706a2dc1f3fSmrg -> priority_queue<typename _Container::value_type, _Container, _Compare>;
707a2dc1f3fSmrg
708a2dc1f3fSmrg template<typename _InputIterator, typename _ValT
709a2dc1f3fSmrg = typename iterator_traits<_InputIterator>::value_type,
710a2dc1f3fSmrg typename _Compare = less<_ValT>,
711a2dc1f3fSmrg typename _Container = vector<_ValT>,
712a2dc1f3fSmrg typename = _RequireInputIter<_InputIterator>,
713c0a68be4Smrg typename = _RequireNotAllocator<_Compare>,
714c0a68be4Smrg typename = _RequireNotAllocator<_Container>>
715a2dc1f3fSmrg priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(),
716a2dc1f3fSmrg _Container = _Container())
717a2dc1f3fSmrg -> priority_queue<_ValT, _Container, _Compare>;
718a2dc1f3fSmrg
719a2dc1f3fSmrg template<typename _Compare, typename _Container, typename _Allocator,
720c0a68be4Smrg typename = _RequireNotAllocator<_Compare>,
721c0a68be4Smrg typename = _RequireNotAllocator<_Container>,
722c0a68be4Smrg typename = _RequireAllocator<_Allocator>>
723a2dc1f3fSmrg priority_queue(_Compare, _Container, _Allocator)
724a2dc1f3fSmrg -> priority_queue<typename _Container::value_type, _Container, _Compare>;
725a2dc1f3fSmrg #endif
726a2dc1f3fSmrg
7271debfc3dSmrg // No equality/comparison operators are provided for priority_queue.
7281debfc3dSmrg
7291debfc3dSmrg #if __cplusplus >= 201103L
7301debfc3dSmrg template<typename _Tp, typename _Sequence, typename _Compare>
7311debfc3dSmrg inline
7321debfc3dSmrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
7331debfc3dSmrg // Constrained free swap overload, see p0185r1
7341debfc3dSmrg typename enable_if<__and_<__is_swappable<_Sequence>,
7351debfc3dSmrg __is_swappable<_Compare>>::value>::type
7361debfc3dSmrg #else
7371debfc3dSmrg void
7381debfc3dSmrg #endif
7391debfc3dSmrg swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
7401debfc3dSmrg priority_queue<_Tp, _Sequence, _Compare>& __y)
7411debfc3dSmrg noexcept(noexcept(__x.swap(__y)))
7421debfc3dSmrg { __x.swap(__y); }
7431debfc3dSmrg
7441debfc3dSmrg template<typename _Tp, typename _Sequence, typename _Compare,
7451debfc3dSmrg typename _Alloc>
7461debfc3dSmrg struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
7471debfc3dSmrg : public uses_allocator<_Sequence, _Alloc>::type { };
7481debfc3dSmrg #endif // __cplusplus >= 201103L
7491debfc3dSmrg
7501debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
7511debfc3dSmrg } // namespace
7521debfc3dSmrg
7531debfc3dSmrg #endif /* _STL_QUEUE_H */
754