зеркало из https://github.com/microsoft/STL.git
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
This commit is contained in:
Родитель
300e85650c
Коммит
02a6ea8b62
|
@ -5,7 +5,7 @@
|
|||
"type": "git",
|
||||
"git": {
|
||||
"repositoryUrl": "https://github.com/llvm/llvm-project.git",
|
||||
"commitHash": "6f0768f64da398d5103d39e83bdc66a5ffd6f0f6"
|
||||
"commitHash": "fc2a5ef9c8754fe3fbdf96483901ca3f13406b35"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e48849a2404128175df25168f961a83d6c0a901e
|
||||
Subproject commit fc2a5ef9c8754fe3fbdf96483901ca3f13406b35
|
|
@ -54,10 +54,7 @@ public:
|
|||
}
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
|
||||
#ifndef __clang__ // TRANSITION, LLVM-41991
|
||||
_NODISCARD
|
||||
#endif // TRANSITION, LLVM-41991
|
||||
friend constexpr bool operator==(const partial_ordering&, const partial_ordering&) noexcept = default;
|
||||
_NODISCARD friend constexpr bool operator==(const partial_ordering&, const partial_ordering&) noexcept = default;
|
||||
#else // ^^^ supports <=> and P1185 / supports neither vvv
|
||||
_NODISCARD friend constexpr bool operator!=(const partial_ordering _Val, _Literal_zero) noexcept {
|
||||
return _Val._Value != 0;
|
||||
|
@ -148,10 +145,7 @@ public:
|
|||
}
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
|
||||
#ifndef __clang__ // TRANSITION, LLVM-41991
|
||||
_NODISCARD
|
||||
#endif // TRANSITION, LLVM-41991
|
||||
friend constexpr bool operator==(const weak_ordering&, const weak_ordering&) noexcept = default;
|
||||
_NODISCARD friend constexpr bool operator==(const weak_ordering&, const weak_ordering&) noexcept = default;
|
||||
#else // ^^^ supports <=> and P1185 / supports neither vvv
|
||||
_NODISCARD friend constexpr bool operator!=(const weak_ordering _Val, _Literal_zero) noexcept {
|
||||
return _Val._Value != 0;
|
||||
|
@ -242,10 +236,7 @@ public:
|
|||
}
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
|
||||
#ifndef __clang__ // TRANSITION, LLVM-41991
|
||||
_NODISCARD
|
||||
#endif // TRANSITION, LLVM-41991
|
||||
friend constexpr bool operator==(const strong_ordering&, const strong_ordering&) noexcept = default;
|
||||
_NODISCARD friend constexpr bool operator==(const strong_ordering&, const strong_ordering&) noexcept = default;
|
||||
#else // ^^^ supports <=> and P1185 / supports neither vvv
|
||||
_NODISCARD friend constexpr bool operator!=(const strong_ordering _Val, _Literal_zero) noexcept {
|
||||
return _Val._Value != 0;
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#ifndef __cpp_lib_concepts
|
||||
#pragma message("The contents of <concepts> are available only with C++20 concepts support.")
|
||||
#else // ^^^ !defined(__cpp_lib_concepts) / defined(__cpp_lib_concepts) vvv
|
||||
#if defined(__clang__) && !defined(_SILENCE_CLANG_CONCEPTS_MESSAGE)
|
||||
#error Despite the presence of some Clang-related bits, this header currently does not support Clang. \
|
||||
You can define _SILENCE_CLANG_CONCEPTS_MESSAGE to silence this message and acknowledge that this is unsupported.
|
||||
#endif // defined(__clang__) && !defined(_SILENCE_CLANG_CONCEPTS_MESSAGE)
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#pragma pack(push, _CRT_PACKING)
|
||||
|
|
|
@ -757,7 +757,7 @@ public:
|
|||
*this /= _Path_cvt<_Valty, value_type>::_Cvt(_Str_out, _Str.c_str(), _Str.size());
|
||||
}
|
||||
|
||||
template <class _InIt, enable_if_t<_Is_iterator_v<_InIt>, int> = 0>
|
||||
template <class _InIt, enable_if_t<conjunction_v<negation<is_same<_InIt, path>>, _Is_iterator<_InIt>>, int> = 0>
|
||||
path(_InIt _First) {
|
||||
using _Valty = _Iter_value_t<_InIt>;
|
||||
basic_string<_Valty> _Str;
|
||||
|
|
|
@ -22,6 +22,39 @@ _STL_DISABLE_CLANG_WARNINGS
|
|||
_STD_BEGIN
|
||||
// CLASS TEMPLATE queue
|
||||
template <class _Ty, class _Container = deque<_Ty>>
|
||||
class queue;
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator==(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c == _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator!=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c != _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator<(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c < _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator>(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c > _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator<=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c <= _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator>=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c >= _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
class queue {
|
||||
public:
|
||||
using value_type = typename _Container::value_type;
|
||||
|
@ -108,18 +141,14 @@ public:
|
|||
_Swap_adl(c, _Right.c);
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator==(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator!=(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator<(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator>(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator<=(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator>=(const queue<_Ty, _Container>&, const queue<_Ty, _Container>&);
|
||||
// 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{};
|
||||
|
@ -136,36 +165,6 @@ template <class _Container, class _Alloc,
|
|||
queue(_Container, _Alloc)->queue<typename _Container::value_type, _Container>;
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator==(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c == _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator!=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c != _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator<(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c < _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator>(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c > _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator<=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c <= _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
_NODISCARD bool operator>=(const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
|
||||
return _Left.c >= _Right.c;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container, enable_if_t<_Is_swappable<_Container>::value, int> = 0>
|
||||
void swap(queue<_Ty, _Container>& _Left, queue<_Ty, _Container>& _Right) noexcept(noexcept(_Left.swap(_Right))) {
|
||||
_Left.swap(_Right);
|
||||
|
|
|
@ -20,6 +20,39 @@ _STL_DISABLE_CLANG_WARNINGS
|
|||
_STD_BEGIN
|
||||
// CLASS TEMPLATE stack
|
||||
template <class _Ty, class _Container = deque<_Ty>>
|
||||
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>
|
||||
class stack {
|
||||
public:
|
||||
using value_type = typename _Container::value_type;
|
||||
|
@ -98,18 +131,14 @@ public:
|
|||
_Swap_adl(c, _Right.c);
|
||||
}
|
||||
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator==(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator!=(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator<(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator>(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator<=(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
template <class _Ty, class _Container>
|
||||
friend bool operator>=(const stack<_Ty, _Container>&, const stack<_Ty, _Container>&);
|
||||
// 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
|
||||
|
||||
protected:
|
||||
_Container c{};
|
||||
|
@ -126,36 +155,6 @@ template <class _Container, class _Alloc,
|
|||
stack(_Container, _Alloc)->stack<typename _Container::value_type, _Container>;
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
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, 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);
|
||||
|
|
|
@ -560,8 +560,8 @@ _NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept {
|
|||
#elif defined(__cpp_constexpr_dynamic_alloc)
|
||||
template <class _Ty>
|
||||
_NODISCARD const _Ty& _Immortalize_memcpy_image() noexcept {
|
||||
constexpr _Ty _Static;
|
||||
return _Static._Storage;
|
||||
static constexpr _Ty _Static;
|
||||
return _Static;
|
||||
}
|
||||
#else // choose immortalize strategy
|
||||
template <class _Ty>
|
||||
|
|
|
@ -210,7 +210,6 @@ utilities\tuple\tuple.tuple\tuple.apply\apply_large_arity.pass.cpp
|
|||
# C++20 P0019R8 "atomic_ref"
|
||||
language.support\support.limits\support.limits.general\atomic.version.pass.cpp
|
||||
|
||||
|
||||
# C++20 P0355R7 "<chrono> Calendars And Time Zones"
|
||||
utilities\time\days.pass.cpp
|
||||
utilities\time\months.pass.cpp
|
||||
|
@ -479,6 +478,28 @@ strings\char.traits\char.traits.specializations\char.traits.specializations.wcha
|
|||
strings\char.traits\char.traits.specializations\char.traits.specializations.wchar.t\copy.pass.cpp
|
||||
strings\char.traits\char.traits.specializations\char.traits.specializations.wchar.t\move.pass.cpp
|
||||
|
||||
# C++20 P1135R6 "The C++20 Synchronization Library"
|
||||
atomics\types.pass.cpp
|
||||
atomics\atomics.types.operations\atomics.types.operations.wait\atomic_wait.pass.cpp
|
||||
thread\thread.barrier\arrive.pass.cpp
|
||||
thread\thread.barrier\arrive_and_drop.pass.cpp
|
||||
thread\thread.barrier\arrive_and_wait.pass.cpp
|
||||
thread\thread.barrier\completion.pass.cpp
|
||||
thread\thread.barrier\max.pass.cpp
|
||||
thread\thread.barrier\version.pass.cpp
|
||||
thread\thread.latch\arrive_and_wait.pass.cpp
|
||||
thread\thread.latch\count_down.pass.cpp
|
||||
thread\thread.latch\max.pass.cpp
|
||||
thread\thread.latch\try_wait.pass.cpp
|
||||
thread\thread.latch\version.pass.cpp
|
||||
thread\thread.semaphore\acquire.pass.cpp
|
||||
thread\thread.semaphore\binary.pass.cpp
|
||||
thread\thread.semaphore\max.pass.cpp
|
||||
thread\thread.semaphore\release.pass.cpp
|
||||
thread\thread.semaphore\timed.pass.cpp
|
||||
thread\thread.semaphore\try_acquire.pass.cpp
|
||||
thread\thread.semaphore\version.pass.cpp
|
||||
|
||||
|
||||
# *** MISSING COMPILER FEATURES ***
|
||||
# C++20 P0722R3 "Efficient sized delete for variable sized classes"
|
||||
|
@ -691,6 +712,10 @@ language.support\support.limits\support.limits.general\string.version.pass.cpp
|
|||
|
||||
# Test needs to be updated for LWG-3320 removing span::const_iterator.
|
||||
containers\views\types.pass.cpp
|
||||
containers\views\span.iterators\begin.pass.cpp
|
||||
containers\views\span.iterators\rbegin.pass.cpp
|
||||
containers\views\span.iterators\end.pass.cpp
|
||||
containers\views\span.iterators\rend.pass.cpp
|
||||
|
||||
# Test needs to be updated for P2116R0 removing the tuple interface of span
|
||||
containers\views\span.tuple\get.fail.cpp
|
||||
|
|
|
@ -1643,6 +1643,7 @@ struct X
|
|||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
}
|
||||
X& operator=(X const&) = default;
|
||||
};
|
||||
|
||||
bool X::throw_now = false;
|
||||
|
@ -7020,7 +7021,7 @@ void test_swap_sfinae() {
|
|||
static_assert(!std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
// Even thought CopyOnly has deleted move operations, those operations
|
||||
// Even though CopyOnly has deleted move operations, those operations
|
||||
// cause optional<CopyOnly> to have implicitly deleted move operations
|
||||
// that decay into copies.
|
||||
using T = TestTypes::CopyOnly;
|
||||
|
|
|
@ -21,10 +21,16 @@ int cube(const int x) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // TRANSITION, Clang 10
|
||||
#pragma clang diagnostic ignored "-Wconstant-evaluated"
|
||||
#else // ^^^ clang / other vvv
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4365) // 'return': conversion from 'size_t' to 'int', signed/unsigned mismatch
|
||||
#pragma warning(disable : 5063) // 'std::is_constant_evaluated' always evaluates to true
|
||||
// in manifestly constant-evaluated expressions
|
||||
#endif // __clang__
|
||||
namespace example { // Test the N4842 [expr.const]/13 example.
|
||||
template <bool>
|
||||
struct X {};
|
||||
|
@ -43,7 +49,11 @@ namespace example { // Test the N4842 [expr.const]/13 example.
|
|||
int p = f(); // m is 13; initialized to 26
|
||||
int q = p + f(); // m is 17 for this call; initialized to 56
|
||||
} // namespace example
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#else // ^^^ clang / other vvv
|
||||
#pragma warning(pop)
|
||||
#endif // __clang__
|
||||
|
||||
int main() {
|
||||
static_assert(is_same_v<decltype(is_constant_evaluated()), bool>);
|
||||
|
|
|
@ -160,18 +160,15 @@ struct weakly_incrementable_archetype : destructible_archetype<I>,
|
|||
|
||||
inline constexpr std::size_t weakly_incrementable_archetype_max = 12;
|
||||
|
||||
template <std::size_t I, class Derived, std::size_t N>
|
||||
struct equality_ops {
|
||||
bool operator==(Derived const&) const requires(I != N);
|
||||
bool operator!=(Derived const&) const requires(I == N + 1) = delete;
|
||||
};
|
||||
|
||||
template <std::size_t I>
|
||||
struct incrementable_archetype : weakly_incrementable_archetype<I>,
|
||||
increment_ops<I, incrementable_archetype<I>, incrementable_archetype<I>>,
|
||||
equality_ops<I, incrementable_archetype<I>, weakly_incrementable_archetype_max> {
|
||||
increment_ops<I, incrementable_archetype<I>, incrementable_archetype<I>> {
|
||||
SEMIREGULAR_OPS(incrementable);
|
||||
using increment_ops<I, incrementable_archetype<I>, incrementable_archetype<I>>::operator++;
|
||||
|
||||
bool operator==(incrementable_archetype const&) const requires(I != weakly_incrementable_archetype_max);
|
||||
bool operator!=(incrementable_archetype const&) const
|
||||
requires(I == weakly_incrementable_archetype_max + 1) = delete;
|
||||
};
|
||||
|
||||
inline constexpr std::size_t incrementable_archetype_max = 14;
|
||||
|
@ -285,10 +282,12 @@ inline constexpr std::size_t input_iterator_archetype_max = 17;
|
|||
|
||||
template <std::size_t I>
|
||||
struct forward_iterator_archetype : input_iterator_archetype<I>,
|
||||
increment_ops<I, forward_iterator_archetype<I>, forward_iterator_archetype<I>>,
|
||||
equality_ops<I, forward_iterator_archetype<I>, input_iterator_archetype_max> {
|
||||
increment_ops<I, forward_iterator_archetype<I>, forward_iterator_archetype<I>> {
|
||||
SEMIREGULAR_OPS(forward_iterator);
|
||||
using increment_ops<I, forward_iterator_archetype<I>, forward_iterator_archetype<I>>::operator++;
|
||||
|
||||
bool operator==(forward_iterator_archetype const&) const requires(I != input_iterator_archetype_max);
|
||||
bool operator!=(forward_iterator_archetype const&) const requires(I == input_iterator_archetype_max + 1) = delete;
|
||||
};
|
||||
|
||||
inline constexpr std::size_t forward_iterator_archetype_max = 19;
|
||||
|
@ -930,8 +929,10 @@ namespace iterator_cust_move_test {
|
|||
STATIC_ASSERT(noexcept(ranges::iter_move(static_cast<int const*>(&some_ints[2]))));
|
||||
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int[]>, int&&>);
|
||||
#ifdef __clang__ // TRANSITION, VSO-1008447
|
||||
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int(int)>, int (&)(int)>);
|
||||
#else // ^^^ no workaround / workaround vvv
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int(int)>, int (*)(int)>);
|
||||
#endif // TRANSITION, VSO-1008447
|
||||
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int[4]>, int&&>);
|
||||
|
@ -941,8 +942,12 @@ namespace iterator_cust_move_test {
|
|||
constexpr int f(int i) noexcept {
|
||||
return i + 1;
|
||||
}
|
||||
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int (*)(int)>, int (&)(int)>);
|
||||
#else // ^^^ no workaround / workaround vvv
|
||||
STATIC_ASSERT(same_as<iter_rvalue_reference_t<int (*)(int)>, int(&&)(int)>);
|
||||
STATIC_ASSERT((ranges::iter_move(&f))(42) == 43);
|
||||
#endif // TRANSITION, VSO-1008447
|
||||
STATIC_ASSERT(ranges::iter_move (&f)(42) == 43);
|
||||
STATIC_ASSERT(noexcept(ranges::iter_move(&f)));
|
||||
|
||||
struct ref_is_lvalue {
|
||||
|
@ -1524,7 +1529,7 @@ namespace std_iterator_tags_test {
|
|||
|
||||
STATIC_ASSERT(std::is_empty_v<T>);
|
||||
STATIC_ASSERT(std::semiregular<T>);
|
||||
T{};
|
||||
(void) T{};
|
||||
|
||||
STATIC_ASSERT(derived_from<T, output_iterator_tag> == derives_from_output);
|
||||
STATIC_ASSERT(derived_from<T, input_iterator_tag> == derives_from_input);
|
||||
|
@ -1552,10 +1557,9 @@ namespace incomplete_test {
|
|||
using E = do_not_instantiate<void>;
|
||||
|
||||
// Verify that the iterator trait aliases do not cause instantiation of pointee types
|
||||
using V = std::iter_value_t<E*>;
|
||||
using D = std::iter_difference_t<E*>;
|
||||
using R = std::iter_reference_t<E*>;
|
||||
using RR = std::iter_rvalue_reference_t<E*>;
|
||||
using V = std::iter_value_t<E*>;
|
||||
using D = std::iter_difference_t<E*>;
|
||||
using R = std::iter_reference_t<E*>;
|
||||
} // namespace incomplete_test
|
||||
|
||||
namespace default_sentinel_test {
|
||||
|
@ -1576,7 +1580,7 @@ namespace default_sentinel_test {
|
|||
// Validate that default_sentinel_t's special member functions are all constexpr
|
||||
default_sentinel_t ds0{}; // default constructor
|
||||
default_sentinel_t ds1{default_sentinel}; // copy constructor
|
||||
default_sentinel_t ds2{std::move(ds0)}; // move constructor
|
||||
[[maybe_unused]] default_sentinel_t ds2{std::move(ds0)}; // move constructor
|
||||
ds0 = default_sentinel; // copy assignment
|
||||
ds1 = std::move(ds0); // move assignment
|
||||
return true;
|
||||
|
@ -1614,7 +1618,7 @@ namespace unreachable_sentinel_test {
|
|||
constexpr bool test(std::integer_sequence<int, Is...>) {
|
||||
unreachable_sentinel_t us0{}; // default constructor is (implicitly) constexpr
|
||||
unreachable_sentinel_t us1{unreachable_sentinel}; // ditto copy constructor
|
||||
unreachable_sentinel_t us2{std::move(us0)}; // ditto move constructor
|
||||
[[maybe_unused]] unreachable_sentinel_t us2{std::move(us0)}; // ditto move constructor
|
||||
us0 = unreachable_sentinel; // ditto copy assignment
|
||||
us1 = std::move(us0); // ditto move assignment
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ constexpr bool test_cpo(T const& obj) {
|
|||
STATIC_ASSERT(std::is_trivially_move_assignable_v<T>);
|
||||
|
||||
// Not required to be constant expressions, but likely portable nonetheless:
|
||||
T value_initialized{};
|
||||
[[maybe_unused]] T value_initialized{};
|
||||
T copy_constructed = obj;
|
||||
T move_constructed = std::move(copy_constructed);
|
||||
copy_constructed = std::move(move_constructed);
|
||||
|
|
|
@ -3347,10 +3347,8 @@ namespace test_relation {
|
|||
|
||||
STATIC_ASSERT(!test<Equivalent, A<0>, B<0>>());
|
||||
STATIC_ASSERT(!test<Equivalent, A<1>, B<1>>());
|
||||
#ifndef __clang__ // TRANSITION, LLVM-44627
|
||||
STATIC_ASSERT(test<Equivalent, A<2>, B<2>>());
|
||||
STATIC_ASSERT(test<Equivalent, A<3>, B<3>>());
|
||||
#endif // TRANSITION, LLVM-44627
|
||||
STATIC_ASSERT(test<Equivalent, A<4>, B<4>>());
|
||||
|
||||
template <unsigned I>
|
||||
|
|
|
@ -1146,15 +1146,15 @@ static_assert(test_remove_cvref<const volatile int& (C::*) (int)>());
|
|||
|
||||
// VSO-707437 "<type_traits>: [Feedback] Template parameter is ambiguous after VS update"
|
||||
template <typename T>
|
||||
void test_VSO_707437_c(T, add_const_t<T>) {}
|
||||
void test_VSO_707437_c(T, add_const_t<T>*) {}
|
||||
template <typename T>
|
||||
void test_VSO_707437_v(T, add_volatile_t<T>) {}
|
||||
void test_VSO_707437_v(T, add_volatile_t<T>*) {}
|
||||
template <typename T>
|
||||
void test_VSO_707437_cv(T, add_cv_t<T>) {}
|
||||
void test_VSO_707437_cv(T, add_cv_t<T>*) {}
|
||||
|
||||
#if _HAS_CXX20
|
||||
template <typename T>
|
||||
void test_VSO_707437_i(T, type_identity_t<T>) {}
|
||||
void test_VSO_707437_i(T, type_identity_t<T>*) {}
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
// VSO-781535 "[RWC][Regression][prod/fe] WebKit failed with error C2938"
|
||||
|
@ -1232,12 +1232,12 @@ STATIC_ASSERT(!HasUnderlyingTypeAlias<ExampleEnum[]>::value);
|
|||
int main() {
|
||||
test_all_function_types();
|
||||
|
||||
test_VSO_707437_c(11L, 22);
|
||||
test_VSO_707437_v(11L, 22);
|
||||
test_VSO_707437_cv(11L, 22);
|
||||
test_VSO_707437_c(11L, nullptr);
|
||||
test_VSO_707437_v(11L, nullptr);
|
||||
test_VSO_707437_cv(11L, nullptr);
|
||||
|
||||
#if _HAS_CXX20
|
||||
test_VSO_707437_i(11L, 22);
|
||||
test_VSO_707437_i(11L, nullptr);
|
||||
#endif // _HAS_CXX20
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ struct is_bool_wrapper<STD true_type> { // true_type is a boolean wrapper
|
|||
static const bool value = true;
|
||||
};
|
||||
|
||||
#define CHECK_TYPEX(t1, t2) CHECK_TYPE(void(t1), void(t2))
|
||||
|
||||
#define T_INTEGRAL_CONSTANT(Ty, NTy, val) \
|
||||
CHECK_TYPE(Ty::type, Ty); \
|
||||
CHECK_TYPE(Ty::value_type, NTy); \
|
||||
|
|
|
@ -48,8 +48,6 @@ namespace { // anonymous namespace
|
|||
public:
|
||||
waiter(Cond& c, Mutex& m, int& r) : cnd(c), mtx(m), result(r) {}
|
||||
|
||||
waiter& operator=(const waiter&); // not defined
|
||||
|
||||
void operator()(int flags) const { // launch thread and synchronize with main thread
|
||||
try { // make sure exceptions don't escape
|
||||
bool res = false;
|
||||
|
|
|
@ -18,11 +18,13 @@ void test_cpp() { // test C++ header
|
|||
|
||||
switch (setjmp(jbuf)) { // jump among cases
|
||||
case 0:
|
||||
CHECK_INT(++ctr, 1);
|
||||
ctr = ctr + 1;
|
||||
CHECK_INT(ctr, 1);
|
||||
STDx longjmp(jbuf, 5);
|
||||
|
||||
case 5:
|
||||
CHECK_INT(++ctr, 2);
|
||||
ctr = ctr + 1;
|
||||
CHECK_INT(ctr, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -230,11 +230,6 @@ struct fwdit { // forward iterator that wraps char *
|
|||
return !(*this == other);
|
||||
}
|
||||
|
||||
fwdit& operator=(const fwdit& other) { // copy
|
||||
ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CHR& operator*() const { // dereference
|
||||
return *ptr;
|
||||
}
|
||||
|
@ -275,11 +270,6 @@ struct bidit { // bidirectional iterator that wraps const char *
|
|||
return !(*this == other);
|
||||
}
|
||||
|
||||
bidit& operator=(const bidit& other) { // copy
|
||||
ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CHR& operator*() const { // dereference
|
||||
return *ptr;
|
||||
}
|
||||
|
|
|
@ -148,11 +148,6 @@ struct fwdit { // forward iterator that wraps char *
|
|||
return !(*this == other);
|
||||
}
|
||||
|
||||
fwdit& operator=(const fwdit& other) { // copy
|
||||
ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CHR& operator*() const { // dereference
|
||||
return *ptr;
|
||||
}
|
||||
|
@ -193,11 +188,6 @@ struct bidit { // bidirectional iterator that wraps const char *
|
|||
return !(*this == other);
|
||||
}
|
||||
|
||||
bidit& operator=(const bidit& other) { // copy
|
||||
ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CHR& operator*() const { // dereference
|
||||
return *ptr;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#define DOUBLE_ALIGN 4
|
||||
#define LDOUBLE_ALIGN 4
|
||||
|
||||
#define CHECK_TYPEX(...) static_assert(STD is_same_v<__VA_ARGS__>, "!is_same_v<" #__VA_ARGS__ ">")
|
||||
|
||||
// TESTS
|
||||
static void t_remove_const() { // test remove_const<T> for various types
|
||||
CHECK_TYPEX(STD remove_const<I>::type, I);
|
||||
|
|
Загрузка…
Ссылка в новой задаче