xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/stl_queue.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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