[libcxx-commits] [libcxx] 26be07b - [libc++][format] Disables narrow string to wide string formatters. (#128355)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 26 08:54:22 PST 2025
Author: Mark de Wever
Date: 2025-02-26T17:54:18+01:00
New Revision: 26be07b8511b703326f2e10864486b5bb9e76196
URL: https://github.com/llvm/llvm-project/commit/26be07b8511b703326f2e10864486b5bb9e76196
DIFF: https://github.com/llvm/llvm-project/commit/26be07b8511b703326f2e10864486b5bb9e76196.diff
LOG: [libc++][format] Disables narrow string to wide string formatters. (#128355)
Implements LWG3944: Formatters converting sequences of char to sequences
of wchar_t
Fixes: #105342
Added:
Modified:
libcxx/docs/Status/Cxx2cIssues.csv
libcxx/include/__format/formatter.h
libcxx/include/__format/formatter_string.h
libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 7dee81a2ba065..d15688d064bb6 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -62,7 +62,7 @@
"`LWG4053 <https://wg21.link/LWG4053>`__","Unary call to ``std::views::repeat`` does not decay the argument","2024-03 (Tokyo)","|Complete|","19",""
"`LWG4054 <https://wg21.link/LWG4054>`__","Repeating a ``repeat_view`` should repeat the view","2024-03 (Tokyo)","|Complete|","19",""
"","","","","",""
-"`LWG3944 <https://wg21.link/LWG3944>`__","Formatters converting sequences of ``char`` to sequences of ``wchar_t``","2024-06 (St. Louis)","","",""
+"`LWG3944 <https://wg21.link/LWG3944>`__","Formatters converting sequences of ``char`` to sequences of ``wchar_t``","2024-06 (St. Louis)","|Complete|","21",""
"`LWG4060 <https://wg21.link/LWG4060>`__","``submdspan`` preconditions do not forbid creating invalid pointer","2024-06 (St. Louis)","","",""
"`LWG4061 <https://wg21.link/LWG4061>`__","Should ``std::basic_format_context`` be default-constructible/copyable/movable?","2024-06 (St. Louis)","|Complete|","19",""
"`LWG4071 <https://wg21.link/LWG4071>`__","``reference_wrapper`` comparisons are not SFINAE-friendly","2024-06 (St. Louis)","|Complete|","19",""
diff --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h
index 10c244b6d1895..e8386f5ca9c79 100644
--- a/libcxx/include/__format/formatter.h
+++ b/libcxx/include/__format/formatter.h
@@ -21,6 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
+struct __disabled_formatter {
+ __disabled_formatter() = delete;
+ __disabled_formatter(const __disabled_formatter&) = delete;
+ __disabled_formatter& operator=(const __disabled_formatter&) = delete;
+};
+
/// The default formatter template.
///
/// [format.formatter.spec]/5
@@ -31,11 +37,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
/// - is_copy_assignable_v<F>, and
/// - is_move_assignable_v<F>.
template <class _Tp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS formatter {
- formatter() = delete;
- formatter(const formatter&) = delete;
- formatter& operator=(const formatter&) = delete;
-};
+struct _LIBCPP_TEMPLATE_VIS formatter : __disabled_formatter {};
# if _LIBCPP_STD_VER >= 23
diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h
index 30084e582214d..112c731e67ed7 100644
--- a/libcxx/include/__format/formatter_string.h
+++ b/libcxx/include/__format/formatter_string.h
@@ -125,6 +125,19 @@ struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT
}
};
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+template <>
+struct formatter<char*, wchar_t> : __disabled_formatter {};
+template <>
+struct formatter<const char*, wchar_t> : __disabled_formatter {};
+template <size_t _Size>
+struct formatter<char[_Size], wchar_t> : __disabled_formatter {};
+template <class _Traits, class _Allocator>
+struct formatter<basic_string<char, _Traits, _Allocator>, wchar_t> : __disabled_formatter {};
+template <class _Traits>
+struct formatter<basic_string_view<char, _Traits>, wchar_t> : __disabled_formatter {};
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<char*> = true;
diff --git a/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp b/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
index ec27acd75e110..ac60307766d24 100644
--- a/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -292,6 +292,21 @@ void test_LWG3631() {
assert_is_not_formattable<std::pair<volatile int, volatile int>, CharT>();
}
+void test_LWG3944() {
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ assert_is_not_formattable<char*, wchar_t>();
+ assert_is_not_formattable<const char*, wchar_t>();
+ assert_is_not_formattable<char[42], wchar_t>();
+ assert_is_not_formattable<std::string, wchar_t>();
+ assert_is_not_formattable<std::string_view, wchar_t>();
+
+ assert_is_formattable<std::vector<char>, wchar_t>();
+ assert_is_formattable<std::set<char>, wchar_t>();
+ assert_is_formattable<std::map<char, char>, wchar_t>();
+ assert_is_formattable<std::tuple<char>, wchar_t>();
+#endif
+}
+
class c {
void f();
void fc() const;
@@ -417,6 +432,7 @@ void test() {
test_P1636<CharT>();
test_P2286<CharT>();
test_LWG3631<CharT>();
+ test_LWG3944();
test_abstract_class<CharT>();
test_disabled<CharT>();
}
More information about the libcxx-commits
mailing list