diff --git a/libcxx/docs/Modules.rst b/libcxx/docs/Modules.rst --- a/libcxx/docs/Modules.rst +++ b/libcxx/docs/Modules.rst @@ -49,10 +49,13 @@ * ``LIBCXX_ENABLE_RANDOM_DEVICE`` * ``LIBCXX_ENABLE_UNICODE`` + * A C++20 based extension + Some of the current limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * There is no official build system support, libc++ has experimental CMake support + * Requires CMake 3.26 for C++20 support * Requires CMake 3.26 for C++23 support * Requires CMake 3.27 for C++26 support * Requires Ninja 1.11 diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -525,6 +525,12 @@ In C++26 formatting pointers gained a type ``P`` and allows to use zero-padding. These options have been retroactively applied to C++20. +Extensions to the C++23 modules ``std`` and ``std.compat`` +---------------------------------------------------------- + +The maintainers of MSVC STL, libstdc++, and libc++ have agreed to make the +C++23 modules ``std`` and ``std.compat`` available in C++20 as an extension. + .. _turning-off-asan: Turning off ASan annotation in containers diff --git a/libcxx/modules/std/algorithm.inc b/libcxx/modules/std/algorithm.inc --- a/libcxx/modules/std/algorithm.inc +++ b/libcxx/modules/std/algorithm.inc @@ -150,10 +150,11 @@ } namespace ranges { +#if _LIBCPP_STD_VER >= 23 // [alg.starts.with], starts with using std::ranges::starts_with; -#if 0 +# if 0 // [alg.ends.with], ends with using std::ranges::ends_with; @@ -167,8 +168,9 @@ using std::ranges::fold_left_with_iter; using std::ranges::fold_left_first_with_iter; using std::ranges::fold_left_first_with_iter; -#endif - } // namespace ranges +# endif +#endif // _LIBCPP_STD_VER >= 23 + } // namespace ranges // [alg.modifying.operations], mutating sequence operations // [alg.copy], copy diff --git a/libcxx/modules/std/bit.inc b/libcxx/modules/std/bit.inc --- a/libcxx/modules/std/bit.inc +++ b/libcxx/modules/std/bit.inc @@ -11,8 +11,10 @@ // [bit.cast], bit_cast using std::bit_cast; +#if _LIBCPP_STD_VER >= 23 // [bit.byteswap], byteswap using std::byteswap; +#endif // _LIBCPP_STD_VER >= 23 // [bit.pow.two], integral powers of 2 using std::bit_ceil; diff --git a/libcxx/modules/std/expected.inc b/libcxx/modules/std/expected.inc --- a/libcxx/modules/std/expected.inc +++ b/libcxx/modules/std/expected.inc @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [expected.unexpected], class template unexpected using std::unexpected; @@ -20,4 +21,5 @@ // [expected.expected], class template expected using std::expected; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/libcxx/modules/std/format.inc b/libcxx/modules/std/format.inc --- a/libcxx/modules/std/format.inc +++ b/libcxx/modules/std/format.inc @@ -42,8 +42,10 @@ // [format.formatter], formatter using std::formatter; +#if _LIBCPP_STD_VER >= 23 // [format.formattable], concept formattable using std::formattable; +#endif // _LIBCPP_STD_VER >= 23 // [format.parse.ctx], class template basic_format_parse_context using std::basic_format_parse_context; @@ -52,6 +54,7 @@ using std::wformat_parse_context; #endif +#if _LIBCPP_STD_VER >= 23 // [format.range], formatting of ranges // [format.range.fmtkind], variable template format_kind using std::format_kind; @@ -59,6 +62,7 @@ // [format.range.formatter], class template range_formatter using std::range_formatter; +#endif // _LIBCPP_STD_VER >= 23 // [format.arg], class template basic_format_arg using std::basic_format_arg; diff --git a/libcxx/modules/std/functional.inc b/libcxx/modules/std/functional.inc --- a/libcxx/modules/std/functional.inc +++ b/libcxx/modules/std/functional.inc @@ -10,7 +10,9 @@ export namespace std { // [func.invoke], invoke using std::invoke; +#if _LIBCPP_STD_VER >= 23 using std::invoke_r; +#endif // _LIBCPP_STD_VER >= 23 // [refwrap], reference_wrapper using std::reference_wrapper; diff --git a/libcxx/modules/std/mdspan.inc b/libcxx/modules/std/mdspan.inc --- a/libcxx/modules/std/mdspan.inc +++ b/libcxx/modules/std/mdspan.inc @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [mdspan.extents], class template extents using std::extents; @@ -24,4 +25,5 @@ // [mdspan.mdspan], class template mdspan using std::mdspan; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/libcxx/modules/std/memory.inc b/libcxx/modules/std/memory.inc --- a/libcxx/modules/std/memory.inc +++ b/libcxx/modules/std/memory.inc @@ -41,9 +41,11 @@ // [allocator.traits], allocator traits using std::allocator_traits; +#if _LIBCPP_STD_VER >= 23 using std::allocation_result; using std::allocate_at_least; +#endif // _LIBCPP_STD_VER >= 23 // [default.allocator], the default allocator using std::allocator; diff --git a/libcxx/modules/std/print.inc b/libcxx/modules/std/print.inc --- a/libcxx/modules/std/print.inc +++ b/libcxx/modules/std/print.inc @@ -8,12 +8,14 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [print.fun], print functions using std::print; using std::println; using std::vprint_nonunicode; -#ifndef _LIBCPP_HAS_NO_UNICODE +# ifndef _LIBCPP_HAS_NO_UNICODE using std::vprint_unicode; -#endif // _LIBCPP_HAS_NO_UNICODE +# endif // _LIBCPP_HAS_NO_UNICODE +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -90,8 +90,10 @@ using std::ranges::borrowed_subrange_t; +#if _LIBCPP_STD_VER >= 23 // [range.utility.conv], range conversions using std::ranges::to; +#endif // _LIBCPP_STD_VER >= 23 // [range.empty], empty view using std::ranges::empty_view; @@ -114,12 +116,14 @@ using std::ranges::views::iota; } // namespace views +#if _LIBCPP_STD_VER >= 23 // [range.repeat], repeat view using std::ranges::repeat_view; namespace views { using std::ranges::views::repeat; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 #ifndef _LIBCPP_HAS_NO_LOCALIZATION // [range.istream], istream view @@ -149,12 +153,14 @@ // [range.owning.view], owning view using std::ranges::owning_view; +#if _LIBCPP_STD_VER >= 23 // [range.as.rvalue], as rvalue view using std::ranges::as_rvalue_view; namespace views { using std::ranges::views::as_rvalue; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 // [range.filter], filter view using std::ranges::filter_view; @@ -259,12 +265,14 @@ using std::ranges::views::values; } // namespace views +#if _LIBCPP_STD_VER >= 23 // [range.zip], zip view using std::ranges::zip_view; namespace views { using std::ranges::views::zip; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 #if 0 // [range.zip.transform], zip transform view @@ -329,6 +337,8 @@ using std::tuple_element; using std::tuple_size; +#if _LIBCPP_STD_VER >= 23 using std::from_range; using std::from_range_t; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/libcxx/modules/std/string.inc b/libcxx/modules/std/string.inc --- a/libcxx/modules/std/string.inc +++ b/libcxx/modules/std/string.inc @@ -68,7 +68,7 @@ using std::hash; // TODO MODULES is this a bug? -#if 1 +#if _LIBCPP_STD_VER >= 23 using std::operator""s; #else inline namespace literals { diff --git a/libcxx/modules/std/thread.inc b/libcxx/modules/std/thread.inc --- a/libcxx/modules/std/thread.inc +++ b/libcxx/modules/std/thread.inc @@ -33,7 +33,9 @@ using std::operator<<; # endif // _LIBCPP_HAS_NO_LOCALIZATION +# if _LIBCPP_STD_VER >= 23 using std::formatter; +# endif // _LIBCPP_STD_VER >= 23 using std::hash; #endif // _LIBCPP_HAS_NO_THREADS diff --git a/libcxx/modules/std/tuple.inc b/libcxx/modules/std/tuple.inc --- a/libcxx/modules/std/tuple.inc +++ b/libcxx/modules/std/tuple.inc @@ -13,9 +13,11 @@ // [tuple.like], concept tuple-like +#if _LIBCPP_STD_VER >= 23 // [tuple.common.ref], common_reference related specializations using std::basic_common_reference; using std::common_type; +#endif // _LIBCPP_STD_VER >= 23 // [tuple.creation], tuple creation functions using std::ignore; diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc --- a/libcxx/modules/std/type_traits.inc +++ b/libcxx/modules/std/type_traits.inc @@ -53,7 +53,9 @@ using std::is_volatile; using std::is_bounded_array; +#if _LIBCPP_STD_VER >= 23 using std::is_scoped_enum; +#endif // _LIBCPP_STD_VER >= 23 using std::is_signed; using std::is_unbounded_array; using std::is_unsigned; @@ -255,7 +257,9 @@ using std::is_nothrow_swappable_v; using std::is_nothrow_swappable_with_v; using std::is_polymorphic_v; +#if _LIBCPP_STD_VER >= 23 using std::is_scoped_enum_v; +#endif // _LIBCPP_STD_VER >= 23 using std::is_signed_v; using std::is_standard_layout_v; using std::is_swappable_v; diff --git a/libcxx/modules/std/utility.inc b/libcxx/modules/std/utility.inc --- a/libcxx/modules/std/utility.inc +++ b/libcxx/modules/std/utility.inc @@ -16,7 +16,9 @@ // [forward], forward/move using std::forward; +#if _LIBCPP_STD_VER >= 23 using std::forward_like; +#endif // _LIBCPP_STD_VER >= 23 using std::move; using std::move_if_noexcept; @@ -37,11 +39,13 @@ using std::in_range; +#if _LIBCPP_STD_VER >= 23 // [utility.underlying], to_underlying using std::to_underlying; // [utility.unreachable], unreachable using std::unreachable; +#endif // _LIBCPP_STD_VER >= 23 // [intseq], compile-time integer sequences using std::index_sequence; @@ -55,8 +59,10 @@ // [pairs], class template pair using std::pair; +#if _LIBCPP_STD_VER >= 23 using std::basic_common_reference; using std::common_type; +#endif // _LIBCPP_STD_VER >= 23 // [pairs.spec], pair specialized algorithms using std::operator==; using std::operator<=>; diff --git a/libcxx/modules/std/vector.inc b/libcxx/modules/std/vector.inc --- a/libcxx/modules/std/vector.inc +++ b/libcxx/modules/std/vector.inc @@ -27,6 +27,8 @@ // hash support using std::hash; +#if _LIBCPP_STD_VER >= 23 // [vector.bool.fmt], formatter specialization for vector using std::formatter; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/libcxx/test/libcxx/module_std.gen.py b/libcxx/test/libcxx/module_std.gen.py --- a/libcxx/test/libcxx/module_std.gen.py +++ b/libcxx/test/libcxx/module_std.gen.py @@ -117,7 +117,7 @@ print( f"""\ //--- module_std.sh.cpp -// UNSUPPORTED{BLOCKLIT}: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED{BLOCKLIT}: c++03, c++11, c++14, c++17 // UNSUPPORTED{BLOCKLIT}: libcpp-has-no-std-modules // UNSUPPORTED{BLOCKLIT}: modules-build diff --git a/libcxx/test/lit.local.cfg b/libcxx/test/lit.local.cfg --- a/libcxx/test/lit.local.cfg +++ b/libcxx/test/lit.local.cfg @@ -34,6 +34,8 @@ std = "26" elif std == "cxx23": std = "23" +elif std == "cxx20": + std = "20" else: std = "" diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -218,9 +218,13 @@ - "**/test-results.xml" - "**/*.abilist" env: - CC: "clang-${LLVM_HEAD_VERSION}" - CXX: "clang++-${LLVM_HEAD_VERSION}" + # Note: Modules require and absolute path for clang-scan-deps + # https://github.com/llvm/llvm-project/issues/61006 + CC: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang" + CXX: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang++" + CMAKE: "/opt/bin/cmake" ENABLE_CLANG_TIDY: "On" + ENABLE_STD_MODULES: "On" agents: queue: "libcxx-builders" os: "linux"