STL/stl/inc/stack

173 строки
6.0 KiB
C++
Исходник Обычный вид История

2019-09-05 01:57:56 +03:00
// stack standard header
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#pragma once
#ifndef _STACK_
#define _STACK_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <deque>
#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 stack
template <class _Ty, class _Container = deque<_Ty>>
Allow Clang10 in the STL (#622) * Allow Clang10 in the STL This PR includes changes necessary to allow (but not require) clang 10 in the STL. It also includes test changes to allow the tests to pass given new clang warnings for deprecated behaviors, and an update to the LLVM reference to get similar changes that have been applied upstream to libc++ tests. Details: * In `<compare>`, remove workarounds for LLVM-41991 in Clang 10 RC1 fixed in RC2. * In `<concepts>`, remove `_SILENCE_CLANG_CONCEPTS_MESSAGE`. * In `<queue>` and `<stack>`, befriend only corresponding specializations of operator templates. * In `<system_error>`, fix the `__cpp_constexpr_dynamic_alloc` implementation of `_Immortalize_memcpy_image` (which we apparently didn't review at all). * In `<experimental/filesystem>`, apply a fix equivalent to the resolution of LWG-3244. * Update `P0220R1_optional` from upstream. * In `P0595R2_is_constant_evaluated`, silence Clang's warning for using `is_constant_evaluated` in a manifestly constant-evaluated context. * In `P0896R4_ranges_iterator_machinery`, fix bogus test cases that were expecting VSO-1008447, silence "unused variable" warnings, and avoid taking advantage of too-lenient MSVC comparison rewrite behavior. * In `P0896R4_ranges_range_machinery`, silence "unused variable" warning. * In `P0898R3_concepts`, Remove workaround for LLVM-44627 in Clang 10 RC1 fixed in RC2. * In `VSO_0000000_type_traits` and `tr1/type_traits5`, silence volatile function parameter deprecation warnings. * In `tr1/condition_variable`, `tr1/regex1`, and `tr1/regex3`, remove unnecessary copy assignment operators that were prompting Clang warnings about the implicitly definition of a copy constructor for such a class being deprecated. * In `tr1/csetjmp`, silence volatile increment deprecation warnings. Skip new libc++ tests: * Various `span` tests that expect `const_iterator` (libc++ doesn't yet implement LWG-3320) * tests for the implementation of P1135R6 "The C++ Synchronization Library" which we do not yet implement
2020-03-20 02:42:55 +03:00
class stack;
template <class _Ty, class _Container>
_NODISCARD bool operator==(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c == _Right.c;
}
template <class _Ty, class _Container>
_NODISCARD bool operator!=(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c != _Right.c;
}
template <class _Ty, class _Container>
_NODISCARD bool operator<(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c < _Right.c;
}
template <class _Ty, class _Container>
_NODISCARD bool operator>(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c > _Right.c;
}
template <class _Ty, class _Container>
_NODISCARD bool operator<=(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c <= _Right.c;
}
template <class _Ty, class _Container>
_NODISCARD bool operator>=(const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c >= _Right.c;
}
template <class _Ty, class _Container>
2019-09-05 01:57:56 +03:00
class stack {
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");
stack() = default;
explicit stack(const _Container& _Cont) : c(_Cont) {}
explicit stack(_Container&& _Cont) noexcept(is_nothrow_move_constructible_v<_Container>) // strengthened
: c(_STD move(_Cont)) {}
template <class _Alloc, enable_if_t<uses_allocator_v<_Container, _Alloc>, int> = 0>
explicit stack(const _Alloc& _Al) noexcept(is_nothrow_constructible_v<_Container, const _Alloc&>) // strengthened
: c(_Al) {}
template <class _Alloc, enable_if_t<uses_allocator_v<_Container, _Alloc>, int> = 0>
stack(const _Container& _Cont, const _Alloc& _Al) : c(_Cont, _Al) {}
template <class _Alloc, enable_if_t<uses_allocator_v<_Container, _Alloc>, int> = 0>
stack(_Container&& _Cont, const _Alloc& _Al) noexcept(
is_nothrow_constructible_v<_Container, _Container, const _Alloc&>) // strengthened
: c(_STD move(_Cont), _Al) {}
template <class _Alloc, enable_if_t<uses_allocator_v<_Container, _Alloc>, int> = 0>
stack(const stack& _Right, const _Alloc& _Al) : c(_Right.c, _Al) {}
template <class _Alloc, enable_if_t<uses_allocator_v<_Container, _Alloc>, int> = 0>
stack(stack&& _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 top() noexcept(noexcept(c.back())) /* strengthened */ {
return c.back();
}
_NODISCARD const_reference top() 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 <class... _Valty>
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_back())) /* strengthened */ {
c.pop_back();
}
void swap(stack& _Right) noexcept(_Is_nothrow_swappable<_Container>::value) {
_Swap_adl(c, _Right.c);
}
Allow Clang10 in the STL (#622) * Allow Clang10 in the STL This PR includes changes necessary to allow (but not require) clang 10 in the STL. It also includes test changes to allow the tests to pass given new clang warnings for deprecated behaviors, and an update to the LLVM reference to get similar changes that have been applied upstream to libc++ tests. Details: * In `<compare>`, remove workarounds for LLVM-41991 in Clang 10 RC1 fixed in RC2. * In `<concepts>`, remove `_SILENCE_CLANG_CONCEPTS_MESSAGE`. * In `<queue>` and `<stack>`, befriend only corresponding specializations of operator templates. * In `<system_error>`, fix the `__cpp_constexpr_dynamic_alloc` implementation of `_Immortalize_memcpy_image` (which we apparently didn't review at all). * In `<experimental/filesystem>`, apply a fix equivalent to the resolution of LWG-3244. * Update `P0220R1_optional` from upstream. * In `P0595R2_is_constant_evaluated`, silence Clang's warning for using `is_constant_evaluated` in a manifestly constant-evaluated context. * In `P0896R4_ranges_iterator_machinery`, fix bogus test cases that were expecting VSO-1008447, silence "unused variable" warnings, and avoid taking advantage of too-lenient MSVC comparison rewrite behavior. * In `P0896R4_ranges_range_machinery`, silence "unused variable" warning. * In `P0898R3_concepts`, Remove workaround for LLVM-44627 in Clang 10 RC1 fixed in RC2. * In `VSO_0000000_type_traits` and `tr1/type_traits5`, silence volatile function parameter deprecation warnings. * In `tr1/condition_variable`, `tr1/regex1`, and `tr1/regex3`, remove unnecessary copy assignment operators that were prompting Clang warnings about the implicitly definition of a copy constructor for such a class being deprecated. * In `tr1/csetjmp`, silence volatile increment deprecation warnings. Skip new libc++ tests: * Various `span` tests that expect `const_iterator` (libc++ doesn't yet implement LWG-3320) * tests for the implementation of P1135R6 "The C++ Synchronization Library" which we do not yet implement
2020-03-20 02:42:55 +03:00
// clang-format off
friend bool operator== <>(const stack&, const stack&);
friend bool operator!= <>(const stack&, const stack&);
friend bool operator< <>(const stack&, const stack&);
friend bool operator> <>(const stack&, const stack&);
friend bool operator<= <>(const stack&, const stack&);
friend bool operator>= <>(const stack&, const stack&);
// clang-format on
2019-09-05 01:57:56 +03:00
protected:
_Container c{};
};
#if _HAS_CXX17
template <class _Container, enable_if_t<!_Is_allocator<_Container>::value, int> = 0>
stack(_Container) -> stack<typename _Container::value_type, _Container>;
2019-09-05 01:57:56 +03:00
template <class _Container, class _Alloc,
enable_if_t<
conjunction_v<negation<_Is_allocator<_Container>>, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>,
int> = 0>
stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>;
2019-09-05 01:57:56 +03:00
#endif // _HAS_CXX17
template <class _Ty, class _Container, enable_if_t<_Is_swappable<_Container>::value, int> = 0>
void swap(stack<_Ty, _Container>& _Left, stack<_Ty, _Container>& _Right) noexcept(noexcept(_Left.swap(_Right))) {
_Left.swap(_Right);
}
template <class _Ty, class _Container, class _Alloc>
struct uses_allocator<stack<_Ty, _Container>, _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 // _STACK_