Mordante updated this revision to Diff 511875.
Mordante added a comment.
CI fixes
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144331/new/
https://reviews.llvm.org/D144331
Files:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes.rst
libcxx/docs/Status/Cxx2b.rst
libcxx/docs/Status/Cxx2bPapers.csv
libcxx/docs/Status/FormatPaper.csv
libcxx/include/__format/parser_std_format_spec.h
libcxx/include/__threading_support
libcxx/include/thread
libcxx/include/version
libcxx/test/libcxx/transitive_includes/cxx03.csv
libcxx/test/libcxx/transitive_includes/cxx11.csv
libcxx/test/libcxx/transitive_includes/cxx14.csv
libcxx/test/libcxx/transitive_includes/cxx17.csv
libcxx/test/libcxx/transitive_includes/cxx20.csv
libcxx/test/libcxx/transitive_includes/cxx2b.csv
libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
Index: libcxx/utils/generate_feature_test_macro_components.py
===================================================================
--- libcxx/utils/generate_feature_test_macro_components.py
+++ libcxx/utils/generate_feature_test_macro_components.py
@@ -327,6 +327,13 @@
"test_suite_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
"libcxx_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
"unimplemented": True,
+ }, {
+ "name": "__cpp_lib_formatters",
+ "values": { "c++2b": 202302 },
+ "headers": ["stacktrace", "thread"],
+ "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+ "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+ "unimplemented": True,
}, {
"name": "__cpp_lib_forward_like",
"values": { "c++2b": 202207 },
Index: libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
===================================================================
--- libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -175,7 +175,8 @@
// Tests for P1636 Formatters for library types
//
// The paper hasn't been voted in so currently all formatters are disabled.
-// TODO validate whether the test is correct after the paper has been accepted.
+// Note the paper has been abandoned, the types are kept since other papers may
+// introduce these formatters.
template <class CharT>
void test_P1636() {
assert_is_not_formattable<std::basic_streambuf<CharT>, CharT>();
@@ -191,7 +192,7 @@
assert_is_not_formattable<std::sub_match<CharT*>, CharT>();
#endif
#ifndef TEST_HAS_NO_THREADS
- assert_is_not_formattable<std::thread::id, CharT>();
+ assert_is_formattable<std::thread::id, CharT>();
#endif
assert_is_not_formattable<std::unique_ptr<int>, CharT>();
}
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
===================================================================
--- libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -9,6 +9,9 @@
// UNSUPPORTED: no-threads
// UNSUPPORTED: no-localization
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
// <thread>
// class thread::id
@@ -18,16 +21,38 @@
// operator<<(basic_ostream<charT, traits>& out, thread::id id);
#include <thread>
+#include <format>
#include <sstream>
#include <cassert>
+#include "make_string.h"
#include "test_macros.h"
-int main(int, char**)
-{
- std::thread::id id0 = std::this_thread::get_id();
- std::ostringstream os;
- os << id0;
+template <class CharT>
+static void test() {
+ std::thread::id id0 = std::this_thread::get_id();
+ std::basic_ostringstream<CharT> os;
+ os << id0;
+
+#if TEST_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+ // C++23 added a formatter specialization for thread::id.
+ // This changed the requirement of ostream to have a
+ // [thread.thread.id]/2
+ // The text representation for the character type charT of an object of
+ // type thread::id is an unspecified sequence of charT ...
+ // This definition is used for both streaming and formatting.
+ //
+ // Test whether the output is identical.
+ std::basic_string<CharT> s = std::format(MAKE_STRING_VIEW(CharT, "{}"), id0);
+ assert(s == os.str());
+#endif
+}
+
+int main(int, char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
return 0;
}
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// <thread>
+
+// template<class charT>
+// struct formatter<thread::id, charT>;
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <thread>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::formatter<std::thread::id, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV("1"));
+
+ test_parse(SV("}"));
+ test_parse(SV("1}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// <thread>
+
+// template<class charT>
+// struct formatter<thread::id, charT>;
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(const T& r, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <thread>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+void test_format(StringViewT expected, std::thread::id arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ const std::formatter<std::thread::id, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ test_format(SV("0"), std::thread::id());
+#else
+ test_format(SV("0x0"), std::thread::id());
+#endif
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// <thread>
+
+// template<class charT>
+// struct formatter<thread::id, charT>;
+
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "format.functions.tests.h"
+#include "test_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(out == expected,
+ TEST_WRITE_CONCATENATED(
+ "\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+ TEST_VALIDATE_EXCEPTION(
+ std::format_error,
+ [&]([[maybe_unused]] const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...)));
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
===================================================================
--- /dev/null
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_THREAD_THREAD_THREADS_THREAD_THREAD_CLASS_THREAD_THREAD_ID_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_THREAD_THREAD_THREADS_THREAD_THREAD_CLASS_THREAD_THREAD_ID_FORMAT_FUNCTIONS_TESTS_H
+
+#include <thread>
+
+#include "format.functions.common.h"
+#include "test_macros.h"
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ // Note the output of std::thread::id is unspecified. The output text is the
+ // same as the stream operator. Since that format is already released this
+ // test follows the practice on existing systems.
+ std::thread::id input{};
+
+ /***** Test the type specific part *****/
+#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ check(SV("0"), SV("{}"), input);
+
+ // *** align-fill & width ***
+ check(SV(" 0"), SV("{:5}"), input);
+ check(SV("0****"), SV("{:*<5}"), input);
+ check(SV("__0__"), SV("{:_^5}"), input);
+ check(SV("::::0"), SV("{::>5}"), input); // This is not a range, so : is allowed as fill character.
+
+ check(SV(" 0"), SV("{:{}}"), input, 5);
+ check(SV("0****"), SV("{:*<{}}"), input, 5);
+ check(SV("__0__"), SV("{:_^{}}"), input, 5);
+ check(SV("####0"), SV("{:#>{}}"), input, 5);
+#else // !defined(__APPLE__) && !defined(__FreeBSD__)
+ check(SV("0x0"), SV("{}"), input);
+
+ // *** align-fill & width ***
+ check(SV(" 0x0"), SV("{:7}"), input);
+ check(SV("0x0****"), SV("{:*<7}"), input);
+ check(SV("__0x0__"), SV("{:_^7}"), input);
+ check(SV("::::0x0"), SV("{::>7}"), input); // This is not a range, so : is allowed as fill character.
+
+ check(SV(" 0x0"), SV("{:{}}"), input, 7);
+ check(SV("0x0****"), SV("{:*<{}}"), input, 7);
+ check(SV("__0x0__"), SV("{:_^{}}"), input, 7);
+ check(SV("####0x0"), SV("{:#>{}}"), input, 7);
+#endif // !defined(__APPLE__) && !defined(__FreeBSD__)
+
+ /***** Test the type generic part *****/
+ check_exception("The format-spec fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{:{<}"), input);
+
+ // *** sign ***
+ check_exception("The replacement field misses a terminating '}'", SV("{:-}"), input);
+ check_exception("The replacement field misses a terminating '}'", SV("{:+}"), input);
+ check_exception("The replacement field misses a terminating '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The replacement field misses a terminating '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The replacement field misses a terminating '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The replacement field misses a terminating '}'", SV("{:L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>(""))
+ check_exception("The replacement field misses a terminating '}'", fmt, input);
+}
+
+#endif // TEST_STD_THREAD_THREAD_THREADS_THREAD_THREAD_CLASS_THREAD_THREAD_ID_FORMAT_FUNCTIONS_TESTS_H
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// <thread>
+
+// template<class charT>
+// struct formatter<thread::id, charT>;
+
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(out == expected,
+ TEST_WRITE_CONCATENATED(
+ "\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
Index: libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -79,6 +79,7 @@
__cpp_lib_expected 202202L [C++2b]
__cpp_lib_filesystem 201703L [C++17]
__cpp_lib_format 202106L [C++20]
+ __cpp_lib_formatters 202302L [C++2b]
__cpp_lib_forward_like 202207L [C++2b]
__cpp_lib_gcd_lcm 201606L [C++17]
__cpp_lib_generic_associative_lookup 201304L [C++14]
@@ -431,6 +432,10 @@
# error "__cpp_lib_format should not be defined before c++20"
# endif
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_forward_like
# error "__cpp_lib_forward_like should not be defined before c++2b"
# endif
@@ -1086,6 +1091,10 @@
# error "__cpp_lib_format should not be defined before c++20"
# endif
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_forward_like
# error "__cpp_lib_forward_like should not be defined before c++2b"
# endif
@@ -1855,6 +1864,10 @@
# error "__cpp_lib_format should not be defined before c++20"
# endif
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_forward_like
# error "__cpp_lib_forward_like should not be defined before c++2b"
# endif
@@ -2903,6 +2916,10 @@
# endif
# endif
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_forward_like
# error "__cpp_lib_forward_like should not be defined before c++2b"
# endif
@@ -4140,6 +4157,19 @@
# endif
# endif
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_formatters
+# error "__cpp_lib_formatters should be defined in c++2b"
+# endif
+# if __cpp_lib_formatters != 202302L
+# error "__cpp_lib_formatters should have the value 202302L in c++2b"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
# ifndef __cpp_lib_forward_like
# error "__cpp_lib_forward_like should be defined in c++2b"
# endif
Index: libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
+++ libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
@@ -17,8 +17,9 @@
// Test the feature test macros defined by <thread>
-/* Constant Value
- __cpp_lib_jthread 201911L [C++20]
+/* Constant Value
+ __cpp_lib_formatters 202302L [C++2b]
+ __cpp_lib_jthread 201911L [C++20]
*/
#include <thread>
@@ -26,24 +27,40 @@
#if TEST_STD_VER < 14
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif
#elif TEST_STD_VER == 14
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif
#elif TEST_STD_VER == 17
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif
#elif TEST_STD_VER == 20
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined before c++2b"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_jthread
# error "__cpp_lib_jthread should be defined in c++20"
@@ -59,6 +76,19 @@
#elif TEST_STD_VER > 20
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_formatters
+# error "__cpp_lib_formatters should be defined in c++2b"
+# endif
+# if __cpp_lib_formatters != 202302L
+# error "__cpp_lib_formatters should have the value 202302L in c++2b"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_formatters
+# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_jthread
# error "__cpp_lib_jthread should be defined in c++2b"
Index: libcxx/test/libcxx/transitive_includes/cxx2b.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx2b.csv
+++ libcxx/test/libcxx/transitive_includes/cxx2b.csv
@@ -584,14 +584,22 @@
system_error stdexcept
system_error string
system_error version
+thread array
thread compare
thread cstddef
+thread cstdint
+thread cstdlib
thread ctime
thread iosfwd
thread limits
+thread locale
thread ratio
+thread stdexcept
+thread string
+thread string_view
thread system_error
thread tuple
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/test/libcxx/transitive_includes/cxx20.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -838,19 +838,26 @@
system_error string
system_error type_traits
system_error version
+thread array
thread compare
thread cstddef
thread cstdint
+thread cstdlib
thread cstring
thread ctime
thread functional
thread iosfwd
thread limits
+thread locale
thread new
thread ratio
+thread stdexcept
+thread string
+thread string_view
thread system_error
thread tuple
thread type_traits
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/test/libcxx/transitive_includes/cxx17.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -832,6 +832,7 @@
system_error string
system_error type_traits
system_error version
+thread array
thread chrono
thread compare
thread cstddef
@@ -841,11 +842,15 @@
thread functional
thread iosfwd
thread limits
+thread locale
thread new
thread ratio
+thread string
+thread string_view
thread system_error
thread tuple
thread type_traits
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/test/libcxx/transitive_includes/cxx14.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -832,6 +832,7 @@
system_error string
system_error type_traits
system_error version
+thread array
thread chrono
thread compare
thread cstddef
@@ -841,11 +842,15 @@
thread functional
thread iosfwd
thread limits
+thread locale
thread new
thread ratio
+thread string
+thread string_view
thread system_error
thread tuple
thread type_traits
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/test/libcxx/transitive_includes/cxx11.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -830,6 +830,7 @@
system_error string
system_error type_traits
system_error version
+thread array
thread chrono
thread compare
thread cstddef
@@ -839,11 +840,15 @@
thread functional
thread iosfwd
thread limits
+thread locale
thread new
thread ratio
+thread string
+thread string_view
thread system_error
thread tuple
thread type_traits
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/test/libcxx/transitive_includes/cxx03.csv
===================================================================
--- libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -829,6 +829,7 @@
system_error string
system_error type_traits
system_error version
+thread array
thread chrono
thread compare
thread cstddef
@@ -838,11 +839,15 @@
thread functional
thread iosfwd
thread limits
+thread locale
thread new
thread ratio
+thread string
+thread string_view
thread system_error
thread tuple
thread type_traits
+thread vector
thread version
tuple compare
tuple cstddef
Index: libcxx/include/version
===================================================================
--- libcxx/include/version
+++ libcxx/include/version
@@ -85,6 +85,7 @@
__cpp_lib_expected 202202L <expected>
__cpp_lib_filesystem 201703L <filesystem>
__cpp_lib_format 202106L <format>
+__cpp_lib_formatters 202302L <stacktrace> <thread>
__cpp_lib_forward_like 202207L <utility>
__cpp_lib_gcd_lcm 201606L <numeric>
__cpp_lib_generic_associative_lookup 201304L <map> <set>
@@ -397,6 +398,9 @@
# define __cpp_lib_constexpr_memory 202202L
# define __cpp_lib_constexpr_typeinfo 202106L
# define __cpp_lib_expected 202202L
+# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+// # define __cpp_lib_formatters 202302L
+# endif
# define __cpp_lib_forward_like 202207L
# define __cpp_lib_invoke_r 202106L
# define __cpp_lib_is_scoped_enum 202011L
Index: libcxx/include/thread
===================================================================
--- libcxx/include/thread
+++ libcxx/include/thread
@@ -64,6 +64,9 @@
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id);
+template<class charT>
+struct formatter<thread::id, charT>;
+
namespace this_thread
{
@@ -84,11 +87,18 @@
*/
#include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
#include <__chrono/steady_clock.h>
#include <__chrono/time_point.h>
+#include <__concepts/arithmetic.h>
#include <__condition_variable/condition_variable.h>
#include <__config>
#include <__exception/terminate.h>
+#include <__format/concepts.h>
+#include <__format/format_parse_context.h>
+#include <__format/formatter.h>
+#include <__format/formatter_integral.h>
+#include <__format/parser_std_format_spec.h>
#include <__functional/hash.h>
#include <__memory/addressof.h>
#include <__memory/unique_ptr.h>
@@ -224,6 +234,45 @@
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
{return __os << __id.__id_;}
+#if _LIBCPP_STD_VER >= 23
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
+ public:
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return __parser_.__parse(__parse_ctx, __format_spec::__fields_fill_align_width);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI auto format(__thread_id __id, auto& __ctx) const -> decltype(__ctx.out()) {
+ // In __threading_support __libcpp_thread_id is either a
+ // unsigned long long or a pthread_t.
+ //
+ // The type of pthread_t is left unspecified in POSIX so it can be any
+ // type. The most logical types are an integral or pointer.
+ // On Linux systems pthread_t is an unsigned long long.
+ // On Apple systems pthread_t is a pointer type.
+ //
+ // Note the output should match what the stream operator does. Since
+ // the ostream operator has been shipped years before this formatter
+ // was added to the Standard, this formatter does what the stream
+ // operator does. This may require platform specific changes.
+
+ using _Tp = decltype(__get_underlying_id(__id));
+ using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>;
+ static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report");
+
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+ if constexpr (is_pointer_v<_Tp>) {
+ __specs.__std_.__alternate_form_ = true;
+ __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
+ }
+ return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs);
+ }
+
+ __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
+};
+#endif // _LIBCPP_STD_VER >= 23
+
class _LIBCPP_TYPE_VIS thread
{
__libcpp_thread_t __t_;
Index: libcxx/include/__threading_support
===================================================================
--- libcxx/include/__threading_support
+++ libcxx/include/__threading_support
@@ -643,6 +643,8 @@
_LIBCPP_INLINE_VISIBILITY
__thread_id(__libcpp_thread_id __id) : __id_(__id) {}
+ _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }
+
friend __thread_id this_thread::get_id() _NOEXCEPT;
friend class _LIBCPP_TYPE_VIS thread;
friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
Index: libcxx/include/__format/parser_std_format_spec.h
===================================================================
--- libcxx/include/__format/parser_std_format_spec.h
+++ libcxx/include/__format/parser_std_format_spec.h
@@ -143,6 +143,7 @@
# if _LIBCPP_STD_VER >= 23
inline constexpr __fields __fields_tuple{.__use_range_fill_ = true};
inline constexpr __fields __fields_range{.__use_range_fill_ = true};
+inline constexpr __fields __fields_fill_align_width{};
# endif
enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
Index: libcxx/docs/Status/FormatPaper.csv
===================================================================
--- libcxx/docs/Status/FormatPaper.csv
+++ libcxx/docs/Status/FormatPaper.csv
@@ -40,5 +40,5 @@
`[format.range.fmtstr] <https://wg21.link/format.range.fmtstr>`_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|,
`[format.range.fmtstr] <https://wg21.link/format.range.fmtstr>`_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|,
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``"
-`[thread.thread.id] <https://wg21.link/thread.thread.id>`_,"Formatting ``thread::id``",,Mark de Wever,|In Progress|,
+`[thread.thread.id] <https://wg21.link/thread.thread.id>`_,"Formatting ``thread::id``",,Mark de Wever,|Complete|,Clang 17
`[stacktrace.format] <https://wg21.link/stacktrace.format>`_,"Formatting ``stacktrace``",A ``<stacktrace>`` implementation,Mark de Wever,,
Index: libcxx/docs/Status/Cxx2bPapers.csv
===================================================================
--- libcxx/docs/Status/Cxx2bPapers.csv
+++ libcxx/docs/Status/Cxx2bPapers.csv
@@ -113,7 +113,7 @@
"`P2713R1 <https://wg21.link/P2713R1>`__","LWG", "Escaping improvements in ``std::format``","February 2023","","","|format|"
"`P2675R1 <https://wg21.link/P2675R1>`__","LWG", "``format``'s width estimation is too approximate and not forward compatible","February 2023","","","|format|"
"`P2572R1 <https://wg21.link/P2572R1>`__","LWG", "``std::format`` fill character allowances","February 2023","","","|format|"
-"`P2693R1 <https://wg21.link/P2693R1>`__","LWG", "Formatting ``thread::id`` and ``stacktrace``","February 2023","","","|format|"
+"`P2693R1 <https://wg21.link/P2693R1>`__","LWG", "Formatting ``thread::id`` and ``stacktrace``","February 2023","|Partial| [#note-P2693R1]_","","|format|"
"`P2679R2 <https://wg21.link/P2679R2>`__","LWG", "Fixing ``std::start_lifetime_as`` for arrays","February 2023","","",""
"`P2674R1 <https://wg21.link/P2674R1>`__","LWG", "A trait for implicit lifetime types","February 2023","","",""
"`P2655R3 <https://wg21.link/P2655R3>`__","LWG", "``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","February 2023","","",""
Index: libcxx/docs/Status/Cxx2b.rst
===================================================================
--- libcxx/docs/Status/Cxx2b.rst
+++ libcxx/docs/Status/Cxx2b.rst
@@ -44,6 +44,9 @@
clang doesn't issue a diagnostic for deprecated using template declarations.
.. [#note-P2520R0] P2520R0: Libc++ implemented this paper as a DR in C++20 as well.
.. [#note-P2711R1] P2711R1: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
+ .. [#note-P2693R1] P1413R3: The formatter for ``std::thread::id`` is implemented.
+ The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is
+ not implemented yet.
.. _issues-status-cxx2b:
Index: libcxx/docs/ReleaseNotes.rst
===================================================================
--- libcxx/docs/ReleaseNotes.rst
+++ libcxx/docs/ReleaseNotes.rst
@@ -39,6 +39,7 @@
------------------
- P2520R0 - ``move_iterator<T*>`` should be a random access iterator
- P1328R1 - ``constexpr type_info::operator==()``
+- P1413R3 - Formatting ``thread::id`` (the ``stacktrace`` is not done yet)
Improvements and New Features
-----------------------------
Index: libcxx/docs/FeatureTestMacroTable.rst
===================================================================
--- libcxx/docs/FeatureTestMacroTable.rst
+++ libcxx/docs/FeatureTestMacroTable.rst
@@ -322,6 +322,8 @@
------------------------------------------------- -----------------
``__cpp_lib_expected`` ``202202L``
------------------------------------------------- -----------------
+ ``__cpp_lib_formatters`` *unimplemented*
+ ------------------------------------------------- -----------------
``__cpp_lib_forward_like`` ``202207L``
------------------------------------------------- -----------------
``__cpp_lib_invoke_r`` ``202106L``
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits