Skip to content

Commit

Permalink
C++20 Standard Library Modules! (#3977)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
StephanTLavavej authored Aug 31, 2023
1 parent bbb6739 commit ab60075
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 17 deletions.
2 changes: 1 addition & 1 deletion stl/inc/ctime
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 15 additions & 13 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<T*> Should Be A Random-Access Iterator
// P2538R1 ADL-Proof projected
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions stl/modules/std.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ export module std;
#include <deque>
#include <exception>
#include <execution>
#if _HAS_CXX23
#include <expected>
#endif // _HAS_CXX23
#include <filesystem>
#include <format>
#include <forward_list>
Expand All @@ -84,7 +86,9 @@ export module std;
#include <numeric>
#include <optional>
#include <ostream>
#if _HAS_CXX23
#include <print>
#endif // _HAS_CXX23
#include <queue>
#include <random>
#include <ranges>
Expand All @@ -96,12 +100,18 @@ export module std;
#include <shared_mutex>
#include <source_location>
#include <span>
#if _HAS_CXX23
#include <spanstream>
#endif // _HAS_CXX23
#include <sstream>
#include <stack>
#if _HAS_CXX23
#include <stacktrace>
#endif // _HAS_CXX23
#include <stdexcept>
#if _HAS_CXX23
#include <stdfloat>
#endif // _HAS_CXX23
#include <stop_token>
#include <streambuf>
#include <string>
Expand Down
20 changes: 20 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <expected>.");
constexpr expected<double, int> test{unexpect, 42};
assert(test.error() == 42);
}
#endif // TEST_STANDARD >= 23

void test_filesystem() {
using namespace std;
Expand Down Expand Up @@ -492,6 +494,7 @@ void test_ostream() {
assert(os.rdbuf() == nullptr);
}

#if TEST_STANDARD >= 23
void test_print() {
using namespace std;
puts("Testing <print>.");
Expand All @@ -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;
Expand Down Expand Up @@ -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 <spanstream>.");
Expand Down Expand Up @@ -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;
Expand All @@ -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 <stacktrace>.");
Expand All @@ -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;
Expand All @@ -778,11 +786,13 @@ void test_stdexcept() {
assert(caught_puppies);
}

#if TEST_STANDARD >= 23
void test_stdfloat() {
using namespace std;
puts("Testing <stdfloat>.");
// `namespace std` is available, so we're done.
}
#endif // TEST_STANDARD >= 23

void test_stop_token() {
using namespace std;
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tests/std/tests/P1502R1_standard_library_header_units/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import <coroutine>;
import <deque>;
import <exception>;
import <execution>;
#if TEST_STANDARD >= 23
import <expected>;
#endif // TEST_STANDARD >= 23
import <filesystem>;
import <format>;
import <forward_list>;
Expand All @@ -54,7 +56,9 @@ import <numbers>;
import <numeric>;
import <optional>;
import <ostream>;
#if TEST_STANDARD >= 23
import <print>;
#endif // TEST_STANDARD >= 23
import <queue>;
import <random>;
import <ranges>;
Expand All @@ -66,12 +70,18 @@ import <set>;
import <shared_mutex>;
import <source_location>;
import <span>;
#if TEST_STANDARD >= 23
import <spanstream>;
#endif // TEST_STANDARD >= 23
import <sstream>;
import <stack>;
#if TEST_STANDARD >= 23
import <stacktrace>;
#endif // TEST_STANDARD >= 23
import <stdexcept>;
#if TEST_STANDARD >= 23
import <stdfloat>;
#endif // TEST_STANDARD >= 23
import <stop_token>;
import <streambuf>;
import <string>;
Expand Down
3 changes: 2 additions & 1 deletion tests/std/tests/P2465R3_standard_library_modules/env.lst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ab60075

Please sign in to comment.