// queue standard header // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #pragma once #ifndef _QUEUE_ #define _QUEUE_ #include #if _STL_COMPILER_PREPROCESSOR #include #include #include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) #pragma warning(disable : _STL_DISABLED_WARNINGS) _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new _STD_BEGIN // CLASS TEMPLATE queue template > class queue; template _NODISCARD bool operator==(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c == _Right.c; } template _NODISCARD bool operator!=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c != _Right.c; } template _NODISCARD bool operator<(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c < _Right.c; } template _NODISCARD bool operator>(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c > _Right.c; } template _NODISCARD bool operator<=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c <= _Right.c; } template _NODISCARD bool operator>=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) { return _Left.c >= _Right.c; } template class queue { public: using value_type = typename _Container::value_type; using reference = typename _Container::reference; using const_reference = typename _Container::const_reference; using size_type = typename _Container::size_type; using container_type = _Container; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); queue() = default; explicit queue(const _Container& _Cont) : c(_Cont) {} explicit queue(_Container&& _Cont) noexcept(is_nothrow_move_constructible_v<_Container>) // strengthened : c(_STD move(_Cont)) {} template , int> = 0> explicit queue(const _Alloc& _Al) noexcept(is_nothrow_constructible_v<_Container, const _Alloc&>) // strengthened : c(_Al) {} template , int> = 0> queue(const _Container& _Cont, const _Alloc& _Al) : c(_Cont, _Al) {} template , int> = 0> queue(_Container&& _Cont, const _Alloc& _Al) noexcept( is_nothrow_constructible_v<_Container, _Container, const _Alloc&>) // strengthened : c(_STD move(_Cont), _Al) {} template , int> = 0> queue(const queue& _Right, const _Alloc& _Al) : c(_Right.c, _Al) {} template , int> = 0> queue(queue&& _Right, const _Alloc& _Al) noexcept( is_nothrow_constructible_v<_Container, _Container, const _Alloc&>) // strengthened : c(_STD move(_Right.c), _Al) {} _NODISCARD bool empty() const noexcept(noexcept(c.empty())) /* strengthened */ { return c.empty(); } _NODISCARD size_type size() const noexcept(noexcept(c.size())) /* strengthened */ { return c.size(); } _NODISCARD reference front() noexcept(noexcept(c.front())) /* strengthened */ { return c.front(); } _NODISCARD const_reference front() const noexcept(noexcept(c.front())) /* strengthened */ { return c.front(); } _NODISCARD reference back() noexcept(noexcept(c.back())) /* strengthened */ { return c.back(); } _NODISCARD const_reference back() const noexcept(noexcept(c.back())) /* strengthened */ { return c.back(); } void push(const value_type& _Val) { c.push_back(_Val); } void push(value_type&& _Val) { c.push_back(_STD move(_Val)); } template decltype(auto) emplace(_Valty&&... _Val) { #if _HAS_CXX17 return c.emplace_back(_STD forward<_Valty>(_Val)...); #else // ^^^ C++17 or newer / C++14 vvv c.emplace_back(_STD forward<_Valty>(_Val)...); #endif // _HAS_CXX17 } void pop() noexcept(noexcept(c.pop_front())) /* strengthened */ { c.pop_front(); } void swap(queue& _Right) noexcept(_Is_nothrow_swappable<_Container>::value) { _Swap_adl(c, _Right.c); } // clang-format off friend bool operator== <>(const queue&, const queue&); friend bool operator!= <>(const queue&, const queue&); friend bool operator< <>(const queue&, const queue&); friend bool operator> <>(const queue&, const queue&); friend bool operator<= <>(const queue&, const queue&); friend bool operator>= <>(const queue&, const queue&); // clang-format on protected: _Container c{}; }; #if _HAS_CXX17 template ::value, int> = 0> queue(_Container) -> queue; template >, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>, int> = 0> queue(_Container, _Alloc) -> queue; #endif // _HAS_CXX17 template ::value, int> = 0> void swap(queue<_Ty, _Container>& _Left, queue<_Ty, _Container>& _Right) noexcept(noexcept(_Left.swap(_Right))) { _Left.swap(_Right); } template struct uses_allocator, _Alloc> : uses_allocator<_Container, _Alloc>::type {}; // CLASS TEMPLATE priority_queue template , class _Pr = less> class priority_queue { public: using value_type = typename _Container::value_type; using reference = typename _Container::reference; using const_reference = typename _Container::const_reference; using size_type = typename _Container::size_type; using container_type = _Container; using value_compare = _Pr; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); priority_queue() = default; explicit priority_queue(const _Pr& _Pred) noexcept( is_nothrow_default_constructible_v<_Container>&& is_nothrow_copy_constructible_v) // strengthened : c(), comp(_Pred) {} priority_queue(const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred) { _STD make_heap(c.begin(), c.end(), comp); } priority_queue(const _Pr& _Pred, _Container&& _Cont) : c(_STD move(_Cont)), comp(_Pred) { _STD make_heap(c.begin(), c.end(), comp); } template priority_queue(_InIt _First, _InIt _Last, const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred) { c.insert(c.end(), _First, _Last); _STD make_heap(c.begin(), c.end(), comp); } template priority_queue(_InIt _First, _InIt _Last) : c(_First, _Last), comp() { _STD make_heap(c.begin(), c.end(), comp); } template priority_queue(_InIt _First, _InIt _Last, const _Pr& _Pred) : c(_First, _Last), comp(_Pred) { _STD make_heap(c.begin(), c.end(), comp); } template priority_queue(_InIt _First, _InIt _Last, const _Pr& _Pred, _Container&& _Cont) : c(_STD move(_Cont)), comp(_Pred) { c.insert(c.end(), _First, _Last); _STD make_heap(c.begin(), c.end(), comp); } template , int> = 0> explicit priority_queue(const _Alloc& _Al) noexcept(is_nothrow_constructible_v<_Container, const _Alloc&>&& is_nothrow_default_constructible_v) // strengthened : c(_Al), comp() {} template , int> = 0> priority_queue(const _Pr& _Pred, const _Alloc& _Al) noexcept(is_nothrow_constructible_v<_Container, const _Alloc&>&& is_nothrow_copy_constructible_v) // strengthened : c(_Al), comp(_Pred) {} template , int> = 0> priority_queue(const _Pr& _Pred, const _Container& _Cont, const _Alloc& _Al) : c(_Cont, _Al), comp(_Pred) { _STD make_heap(c.begin(), c.end(), comp); } template , int> = 0> priority_queue(const _Pr& _Pred, _Container&& _Cont, const _Alloc& _Al) : c(_STD move(_Cont), _Al), comp(_Pred) { _STD make_heap(c.begin(), c.end(), comp); } template , int> = 0> priority_queue(const priority_queue& _Right, const _Alloc& _Al) : c(_Right.c, _Al), comp(_Right.comp) {} template , int> = 0> priority_queue(priority_queue&& _Right, const _Alloc& _Al) noexcept( is_nothrow_constructible_v<_Container, _Container, const _Alloc&>&& is_nothrow_move_constructible_v) // strengthened : c(_STD move(_Right.c), _Al), comp(_STD move(_Right.comp)) {} _NODISCARD bool empty() const noexcept(noexcept(c.empty())) /* strengthened */ { return c.empty(); } _NODISCARD size_type size() const noexcept(noexcept(c.size())) /* strengthened */ { return c.size(); } _NODISCARD const_reference top() const noexcept(noexcept(c.front())) /* strengthened */ { return c.front(); } void push(const value_type& _Val) { c.push_back(_Val); _STD push_heap(c.begin(), c.end(), comp); } void push(value_type&& _Val) { c.push_back(_STD move(_Val)); _STD push_heap(c.begin(), c.end(), comp); } template void emplace(_Valty&&... _Val) { c.emplace_back(_STD forward<_Valty>(_Val)...); _STD push_heap(c.begin(), c.end(), comp); } void pop() { _STD pop_heap(c.begin(), c.end(), comp); c.pop_back(); } void swap(priority_queue& _Right) noexcept( _Is_nothrow_swappable<_Container>::value&& _Is_nothrow_swappable<_Pr>::value) { _Swap_adl(c, _Right.c); _Swap_adl(comp, _Right.comp); } protected: _Container c{}; _Pr comp{}; }; #if _HAS_CXX17 template >, negation<_Is_allocator<_Container>>>, int> = 0> priority_queue(_Pr, _Container) -> priority_queue; template >, class _Container = vector<_Iter_value_t<_Iter>>, enable_if_t, negation<_Is_allocator<_Pr>>, negation<_Is_allocator<_Container>>>, int> = 0> priority_queue(_Iter, _Iter, _Pr = _Pr(), _Container = _Container()) -> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>; template >, negation<_Is_allocator<_Container>>, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>, int> = 0> priority_queue(_Pr, _Container, _Alloc) -> priority_queue; #endif // _HAS_CXX17 template ::value && _Is_swappable<_Pr>::value, int> = 0> void swap(priority_queue<_Ty, _Container, _Pr>& _Left, priority_queue<_Ty, _Container, _Pr>& _Right) noexcept( noexcept(_Left.swap(_Right))) { _Left.swap(_Right); } template struct uses_allocator, _Alloc> : uses_allocator<_Container, _Alloc>::type {}; _STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) #endif // _STL_COMPILER_PREPROCESSOR #endif // _QUEUE_