From ab600751924207014ab02f7422ee00a6843e2f0f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 31 Aug 2023 09:29:32 -0700 Subject: [PATCH] C++20 Standard Library Modules! (#3977) After discussion and buy-in from other Standard Library maintainers, we've decided to support the named modules (`std` and `std.compat`) from C++23 in C++20 mode. --- stl/inc/ctime | 2 +- stl/inc/yvals_core.h | 28 ++++++++++--------- stl/modules/std.ixx | 10 +++++++ .../include/test_header_units_and_modules.hpp | 20 +++++++++++++ .../env.lst | 3 +- .../test.cpp | 10 +++++++ .../P2465R3_standard_library_modules/env.lst | 3 +- .../test.compile.pass.cpp | 2 +- 8 files changed, 61 insertions(+), 17 deletions(-) diff --git a/stl/inc/ctime b/stl/inc/ctime index 584900aec6..905b090e47 100644 --- a/stl/inc/ctime +++ b/stl/inc/ctime @@ -29,7 +29,7 @@ _EXPORT_STD using _CSTD strftime; _EXPORT_STD using _CSTD timespec; #endif // _HAS_CXX17 -#if _HAS_CXX23 && defined(_BUILD_STD_MODULE) // TRANSITION, OS-33790456 +#ifdef _BUILD_STD_MODULE // TRANSITION, OS-33790456 _STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index aea4cc51f7..09d2cc7eaa 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -292,6 +292,7 @@ // P2418R2 Add Support For std::generator-like Types To std::format // P2419R2 Clarify Handling Of Encodings In Localized Formatting Of chrono Types // P2432R1 Fix istream_view +// P2465R3 Standard Library Modules std And std.compat // P2508R1 basic_format_string, format_string, wformat_string // P2520R0 move_iterator Should Be A Random-Access Iterator // P2538R1 ADL-Proof projected @@ -365,7 +366,6 @@ // P2443R1 views::chunk_by // P2445R1 forward_like() // P2446R2 views::as_rvalue -// P2465R3 Standard Library Modules std And std.compat // P2467R1 ios_base::noreplace: Exclusive Mode For fstreams // P2474R2 views::repeat // P2494R2 Relaxing Range Adaptors To Allow Move-Only Types @@ -928,11 +928,14 @@ _EMIT_STL_ERROR(STL1001, "Unexpected compiler version, expected MSVC 19.36 or ne #endif // ^^^ inline (not constexpr) in C++20 and earlier ^^^ // P2465R3 Standard Library Modules std And std.compat -#if _HAS_CXX23 && defined(_BUILD_STD_MODULE) +#ifdef _BUILD_STD_MODULE +#if !_HAS_CXX20 +#error The Standard Library Modules are available only with C++20 or later. +#endif // ^^^ !_HAS_CXX20 ^^^ #define _EXPORT_STD export -#else // _HAS_CXX23 && defined(_BUILD_STD_MODULE) +#else // ^^^ defined(_BUILD_STD_MODULE) / !defined(_BUILD_STD_MODULE) vvv #define _EXPORT_STD -#endif // _HAS_CXX23 && defined(_BUILD_STD_MODULE) +#endif // ^^^ !defined(_BUILD_STD_MODULE) ^^^ // P0607R0 Inline Variables For The STL #if _HAS_CXX17 @@ -1752,6 +1755,10 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_list_remove_return_type 201806L #define __cpp_lib_math_constants 201907L +#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, Clang and EDG support for modules +#define __cpp_lib_modules 202207L +#endif // !defined(__clang__) && !defined(__EDG__) + #ifdef __cpp_lib_concepts #define __cpp_lib_move_iterator_concept 202207L #endif // defined(__cpp_lib_concepts) @@ -1793,15 +1800,10 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_formatters 202302L #endif // defined(__cpp_lib_concepts) -#define __cpp_lib_forward_like 202207L -#define __cpp_lib_invoke_r 202106L -#define __cpp_lib_ios_noreplace 202207L -#define __cpp_lib_is_scoped_enum 202011L - -#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, Clang and EDG support for modules -#define __cpp_lib_modules 202207L -#endif // !defined(__clang__) && !defined(__EDG__) - +#define __cpp_lib_forward_like 202207L +#define __cpp_lib_invoke_r 202106L +#define __cpp_lib_ios_noreplace 202207L +#define __cpp_lib_is_scoped_enum 202011L #define __cpp_lib_move_only_function 202110L #ifdef __cpp_lib_concepts diff --git a/stl/modules/std.ixx b/stl/modules/std.ixx index 326d944d74..fed223a5fc 100644 --- a/stl/modules/std.ixx +++ b/stl/modules/std.ixx @@ -57,7 +57,9 @@ export module std; #include #include #include +#if _HAS_CXX23 #include +#endif // _HAS_CXX23 #include #include #include @@ -84,7 +86,9 @@ export module std; #include #include #include +#if _HAS_CXX23 #include +#endif // _HAS_CXX23 #include #include #include @@ -96,12 +100,18 @@ export module std; #include #include #include +#if _HAS_CXX23 #include +#endif // _HAS_CXX23 #include #include +#if _HAS_CXX23 #include +#endif // _HAS_CXX23 #include +#if _HAS_CXX23 #include +#endif // _HAS_CXX23 #include #include #include diff --git a/tests/std/include/test_header_units_and_modules.hpp b/tests/std/include/test_header_units_and_modules.hpp index ce362844dc..41b75f4d3b 100644 --- a/tests/std/include/test_header_units_and_modules.hpp +++ b/tests/std/include/test_header_units_and_modules.hpp @@ -216,12 +216,14 @@ void test_execution() { assert(count(execution::par, begin(arr), end(arr), 0) == 4); } +#if TEST_STANDARD >= 23 void test_expected() { using namespace std; puts("Testing ."); constexpr expected test{unexpect, 42}; assert(test.error() == 42); } +#endif // TEST_STANDARD >= 23 void test_filesystem() { using namespace std; @@ -492,6 +494,7 @@ void test_ostream() { assert(os.rdbuf() == nullptr); } +#if TEST_STANDARD >= 23 void test_print() { using namespace std; puts("Testing ."); @@ -501,6 +504,7 @@ void test_print() { println(cout, "The answer to life, the universe, and everything: {}", 42); #endif // _CPPRTTI } +#endif // TEST_STANDARD >= 23 void test_queue() { using namespace std; @@ -688,6 +692,7 @@ void test_span() { static_assert(mid[0] == 22 && mid[1] == 33 && mid[2] == 44); } +#if TEST_STANDARD >= 23 void test_spanstream() { using namespace std; puts("Testing ."); @@ -720,6 +725,7 @@ void test_spanstream() { s << 10 << 20 << 30; assert(equal(begin(s.span()), end(s.span()), begin(expected_val), end(expected_val))); } +#endif // TEST_STANDARD >= 23 void test_sstream() { using namespace std; @@ -746,6 +752,7 @@ void test_stack() { assert(s.empty()); } +#if TEST_STANDARD >= 23 __declspec(dllexport) void test_stacktrace() { // export test_stacktrace to have it named even without debug info using namespace std; puts("Testing ."); @@ -761,6 +768,7 @@ __declspec(dllexport) void test_stacktrace() { // export test_stacktrace to have assert(desc == "test_stacktrace"); } +#endif // TEST_STANDARD >= 23 void test_stdexcept() { using namespace std; @@ -778,11 +786,13 @@ void test_stdexcept() { assert(caught_puppies); } +#if TEST_STANDARD >= 23 void test_stdfloat() { using namespace std; puts("Testing ."); // `namespace std` is available, so we're done. } +#endif // TEST_STANDARD >= 23 void test_stop_token() { using namespace std; @@ -1080,7 +1090,9 @@ void all_cpp_header_tests() { test_deque(); test_exception(); test_execution(); +#if TEST_STANDARD >= 23 test_expected(); +#endif // TEST_STANDARD >= 23 test_filesystem(); test_format(); test_forward_list(); @@ -1107,7 +1119,9 @@ void all_cpp_header_tests() { test_numeric(); test_optional(); test_ostream(); +#if TEST_STANDARD >= 23 test_print(); +#endif // TEST_STANDARD >= 23 test_queue(); test_random(); test_ranges(); @@ -1119,12 +1133,18 @@ void all_cpp_header_tests() { test_shared_mutex(); test_source_location(); test_span(); +#if TEST_STANDARD >= 23 test_spanstream(); +#endif // TEST_STANDARD >= 23 test_sstream(); test_stack(); +#if TEST_STANDARD >= 23 test_stacktrace(); +#endif // TEST_STANDARD >= 23 test_stdexcept(); +#if TEST_STANDARD >= 23 test_stdfloat(); +#endif // TEST_STANDARD >= 23 test_stop_token(); test_streambuf(); test_string(); diff --git a/tests/std/tests/P1502R1_standard_library_header_units/env.lst b/tests/std/tests/P1502R1_standard_library_header_units/env.lst index 9cdd80a2eb..4912f8d803 100644 --- a/tests/std/tests/P1502R1_standard_library_header_units/env.lst +++ b/tests/std/tests/P1502R1_standard_library_header_units/env.lst @@ -5,7 +5,8 @@ RUNALL_INCLUDE ..\..\..\universal_prefix.lst RUNALL_CROSSLIST PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER" RUNALL_CROSSLIST -PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /std:c++latest" +PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=20 /std:c++20" +PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=23 /std:c++latest" RUNALL_CROSSLIST PM_CL="/Zc:preprocessor" RUNALL_CROSSLIST diff --git a/tests/std/tests/P1502R1_standard_library_header_units/test.cpp b/tests/std/tests/P1502R1_standard_library_header_units/test.cpp index f9fa3090a2..66fbc4ea5a 100644 --- a/tests/std/tests/P1502R1_standard_library_header_units/test.cpp +++ b/tests/std/tests/P1502R1_standard_library_header_units/test.cpp @@ -27,7 +27,9 @@ import ; import ; import ; import ; +#if TEST_STANDARD >= 23 import ; +#endif // TEST_STANDARD >= 23 import ; import ; import ; @@ -54,7 +56,9 @@ import ; import ; import ; import ; +#if TEST_STANDARD >= 23 import ; +#endif // TEST_STANDARD >= 23 import ; import ; import ; @@ -66,12 +70,18 @@ import ; import ; import ; import ; +#if TEST_STANDARD >= 23 import ; +#endif // TEST_STANDARD >= 23 import ; import ; +#if TEST_STANDARD >= 23 import ; +#endif // TEST_STANDARD >= 23 import ; +#if TEST_STANDARD >= 23 import ; +#endif // TEST_STANDARD >= 23 import ; import ; import ; diff --git a/tests/std/tests/P2465R3_standard_library_modules/env.lst b/tests/std/tests/P2465R3_standard_library_modules/env.lst index 759f0d1802..c399bd0ee5 100644 --- a/tests/std/tests/P2465R3_standard_library_modules/env.lst +++ b/tests/std/tests/P2465R3_standard_library_modules/env.lst @@ -5,7 +5,8 @@ RUNALL_INCLUDE ..\..\..\universal_prefix.lst RUNALL_CROSSLIST PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /D_STL_CALL_ABORT_INSTEAD_OF_INVALID_PARAMETER" RUNALL_CROSSLIST -PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /std:c++latest" +PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=20 /std:c++20" +PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=23 /std:c++latest" RUNALL_CROSSLIST PM_CL="/Zc:preprocessor" RUNALL_CROSSLIST diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 177381531f..e130dd7f54 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -1506,7 +1506,7 @@ STATIC_ASSERT(__cpp_lib_memory_resource == 201603L); #endif #endif -#if _HAS_CXX23 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, Clang and EDG support for modules +#if _HAS_CXX20 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, Clang and EDG support for modules #ifndef __cpp_lib_modules #error __cpp_lib_modules is not defined #elif __cpp_lib_modules != 202207L