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 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