[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