diff --git a/stl/inc/coroutine b/stl/inc/coroutine index ad2c2f30dd8..a9f8f729737 100644 --- a/stl/inc/coroutine +++ b/stl/inc/coroutine @@ -11,16 +11,19 @@ #ifdef _RESUMABLE_FUNCTIONS_SUPPORTED #pragma message("The contents of are not available with /await.") -#pragma message("Remove /await for standard coroutines or use for legacy /await support.") +#pragma message("Remove /await or use /await:strict for standard coroutines.") +#pragma message("Use for legacy /await support.") #else // ^^^ /await ^^^ / vvv no /await vvv #ifndef __cpp_lib_coroutine -#pragma message("The contents of are available only with C++20 or later.") -#else // ^^^ __cpp_lib_coroutine not defined / __cpp_lib_coroutine defined vvv +#pragma message("The contents of are available only with C++20 or later or /await:strict.") +#else // ^^^ is not available / is available vvv #ifndef _ALLOW_COROUTINE_ABI_MISMATCH #pragma detect_mismatch("_COROUTINE_ABI", "2") #endif // _ALLOW_COROUTINE_ABI_MISMATCH +#if _HAS_CXX20 #include +#endif // _HAS_CXX20 #include #pragma pack(push, _CRT_PACKING) @@ -156,6 +159,7 @@ _NODISCARD constexpr bool operator==(const coroutine_handle<> _Left, const corou return _Left.address() == _Right.address(); } +#if _HAS_CXX20 _NODISCARD constexpr strong_ordering operator<=>( const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { #ifdef __cpp_lib_concepts @@ -164,6 +168,27 @@ _NODISCARD constexpr strong_ordering operator<=>( return _Left.address() <=> _Right.address(); #endif // __cpp_lib_concepts } +#else // ^^^ <=> exists / <=> does not exist vvv +_NODISCARD constexpr bool operator!=(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { + return !(_Left == _Right); +} + +_NODISCARD constexpr bool operator<(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { + return less{}(_Left.address(), _Right.address()); +} + +_NODISCARD constexpr bool operator>(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { + return _Right < _Left; +} + +_NODISCARD constexpr bool operator<=(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { + return !(_Left > _Right); +} + +_NODISCARD constexpr bool operator>=(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept { + return !(_Left < _Right); +} +#endif // _HAS_CXX20 template struct hash> { @@ -246,7 +271,7 @@ _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) -#endif // __cpp_lib_coroutine +#endif // is available #endif // _RESUMABLE_FUNCTIONS_SUPPORTED #endif // _STL_COMPILER_PREPROCESSOR #endif // _COROUTINE_ diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index a4d0d1a1aaf..973143b93e3 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1220,10 +1220,6 @@ #define __cpp_lib_constexpr_vector 201907L #endif // defined(__cpp_constexpr_dynamic_alloc) && !defined(__clang__) -#ifdef __cpp_impl_coroutine // TRANSITION, Clang coroutine support -#define __cpp_lib_coroutine 201902L -#endif // __cpp_impl_coroutine - #define __cpp_lib_destroying_delete 201806L #define __cpp_lib_endian 201907L #define __cpp_lib_erase_if 202002L @@ -1296,6 +1292,10 @@ #define __cpp_lib_shared_ptr_arrays 201611L // P0497R0 Fixing shared_ptr For Arrays #endif // _HAS_CXX20 +#if defined(__cpp_impl_coroutine) || defined(_DOWNLEVEL_COROUTINES_SUPPORTED) // TRANSITION, Clang coroutine support +#define __cpp_lib_coroutine 201902L +#endif // __cpp_impl_coroutine + // EXPERIMENTAL #define __cpp_lib_experimental_erase_if 201411L #define __cpp_lib_experimental_filesystem 201406L diff --git a/tests/std/tests/P0912R5_coroutine/env.lst b/tests/std/tests/P0912R5_coroutine/env.lst index 642f530ffad..f873150e6bb 100644 --- a/tests/std/tests/P0912R5_coroutine/env.lst +++ b/tests/std/tests/P0912R5_coroutine/env.lst @@ -1,4 +1,21 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -RUNALL_INCLUDE ..\usual_latest_matrix.lst +RUNALL_INCLUDE ..\prefix.lst +RUNALL_CROSSLIST +PM_CL="/EHsc /MD /await:strict /std:c++14" +PM_CL="/EHsc /MD /await:strict /std:c++14 /permissive-" +PM_CL="/EHsc /MTd /await:strict /std:c++14 /permissive- /Zc:preprocessor" +PM_CL="/EHsc /MD /await:strict /std:c++14 /permissive- /analyze:only /analyze:autolog-" +PM_CL="/EHsc /MD /await:strict /std:c++17" +PM_CL="/EHsc /MD /await:strict /std:c++17 /permissive-" +PM_CL="/EHsc /MTd /await:strict /std:c++17 /permissive- /Zc:preprocessor" +PM_CL="/EHsc /MD /await:strict /std:c++17 /permissive- /analyze:only /analyze:autolog-" +PM_CL="/EHsc /MD /std:c++latest /permissive" +PM_CL="/EHsc /MD /std:c++latest /permissive-" +PM_CL="/EHsc /MTd /std:c++latest /permissive- /Zc:preprocessor" +PM_CL="/EHsc /MD /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/BE /c /EHsc /MD /std:c++latest /permissive-" +PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing /EHsc /MD /std:c++latest /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing /EHsc /MTd /std:c++latest /permissive-" diff --git a/tests/std/tests/P0912R5_coroutine/test.cpp b/tests/std/tests/P0912R5_coroutine/test.cpp index 0aa48651cb6..2edce782cee 100644 --- a/tests/std/tests/P0912R5_coroutine/test.cpp +++ b/tests/std/tests/P0912R5_coroutine/test.cpp @@ -9,6 +9,8 @@ #include using namespace std; +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + int g_tasks_destroyed{0}; struct Task { @@ -33,7 +35,8 @@ struct Task { void await_resume() noexcept {} coroutine_handle<> await_suspend(coroutine_handle h) noexcept { - if (auto& pre = h.promise().previous; pre) { + auto& pre = h.promise().previous; + if (pre) { return pre; // resume awaiting coroutine } @@ -97,50 +100,50 @@ Task triangular_number(const int n) { void test_noop_handle() { // Validate noop_coroutine_handle const noop_coroutine_handle noop = noop_coroutine(); - static_assert(noexcept(noop_coroutine())); + STATIC_ASSERT(noexcept(noop_coroutine())); const coroutine_handle<> as_void = noop; - static_assert(noexcept(static_cast>(noop_coroutine()))); + STATIC_ASSERT(noexcept(static_cast>(noop_coroutine()))); assert(noop); assert(as_void); - static_assert(noexcept(static_cast(noop))); - static_assert(noexcept(static_cast(as_void))); + STATIC_ASSERT(noexcept(static_cast(noop))); + STATIC_ASSERT(noexcept(static_cast(as_void))); assert(!noop.done()); assert(!as_void.done()); - static_assert(noexcept(noop.done())); - static_assert(noexcept(as_void.done())); + STATIC_ASSERT(noexcept(noop.done())); + STATIC_ASSERT(noexcept(as_void.done())); assert(noop); assert(as_void); noop(); as_void(); - static_assert(noexcept(noop())); + STATIC_ASSERT(noexcept(noop())); assert(noop); assert(as_void); noop.resume(); as_void.resume(); - static_assert(noexcept(noop.resume())); + STATIC_ASSERT(noexcept(noop.resume())); assert(noop); assert(as_void); noop.destroy(); as_void.destroy(); - static_assert(noexcept(noop.destroy())); + STATIC_ASSERT(noexcept(noop.destroy())); assert(noop); assert(as_void); assert(&noop.promise() != nullptr); - static_assert(noexcept(noop.promise())); + STATIC_ASSERT(noexcept(noop.promise())); assert(noop); assert(as_void); assert(noop.address() != nullptr); assert(noop.address() == as_void.address()); - static_assert(noexcept(noop.address())); - static_assert(noexcept(as_void.address())); + STATIC_ASSERT(noexcept(noop.address())); + STATIC_ASSERT(noexcept(as_void.address())); } int main() {