From 7519da40d272ab7f060683c80766adf3b4a8b5ce Mon Sep 17 00:00:00 2001 From: cpplearner Date: Fri, 26 Apr 2024 20:55:32 +0800 Subject: [PATCH] Measure display width in tuple formatter --- stl/inc/format | 12 +++++++-- .../test.cpp | 9 +++++++ .../test.cpp | 25 ++++++++++++++++--- .../P2286R8_text_formatting_tuple/test.cpp | 13 +++++++--- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 00c0aa1e2f4..15fbbfd7f34 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -3961,6 +3961,13 @@ _NODISCARD size_t formatted_size(const locale& _Loc, const wformat_string<_Types _FMT_P2286_END #if _HAS_CXX23 +template +_NODISCARD int _Measure_display_width(const basic_string_view<_CharT> _Value) { + int _Width = -1; + (void) _Measure_string_prefix(_Value, _Width); + return _Width; +} + enum class _Fmt_tuple_type : uint8_t { _None, _Key_value, _No_brackets }; template @@ -4127,8 +4134,9 @@ protected: }(index_sequence_for<_ArgTypes...>{}); _STD _Copy_unchecked(_Closing_bracket._Unchecked_begin(), _Closing_bracket._Unchecked_end(), _Tmp_ctx.out()); - return _STD _Write_aligned(_Fmt_ctx.out(), static_cast(_Tmp_buf.size()), _Format_specs, _Fmt_align::_Left, - [&](typename _FormatContext::iterator _Out) { + const int _Width = _Measure_display_width<_CharT>(_Tmp_buf); + return _STD _Write_aligned( + _Fmt_ctx.out(), _Width, _Format_specs, _Fmt_align::_Left, [&](typename _FormatContext::iterator _Out) { return _STD _Fmt_write(_STD move(_Out), basic_string_view<_CharT>{_Tmp_buf}); }); } diff --git a/tests/std/tests/P2286R8_text_formatting_escaping_legacy_text_encoding/test.cpp b/tests/std/tests/P2286R8_text_formatting_escaping_legacy_text_encoding/test.cpp index 9473f66c566..b01f72fae10 100644 --- a/tests/std/tests/P2286R8_text_formatting_escaping_legacy_text_encoding/test.cpp +++ b/tests/std/tests/P2286R8_text_formatting_escaping_legacy_text_encoding/test.cpp @@ -17,6 +17,15 @@ void test_escaped_string() { assert(format("{:?}", "\x81\x40\x40\x81") == "\"\\u{3000}\x40\\x{81}\""); } +template +void test_tuple_or_pair_escaping(TupleOrPair&& input) { + get<1>(input) = "hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O + assert(format("{}", input) == "('*', \"hell\uff2f\")"); + assert(format("{:#^16}", input) == "('*', \"hell\uff2f\")#"); +} + int main() { test_escaped_string(); + test_tuple_or_pair_escaping(make_pair('*', "")); + test_tuple_or_pair_escaping(make_tuple('*', "")); } diff --git a/tests/std/tests/P2286R8_text_formatting_escaping_utf8/test.cpp b/tests/std/tests/P2286R8_text_formatting_escaping_utf8/test.cpp index 5c21fb5423c..bbc517274b0 100644 --- a/tests/std/tests/P2286R8_text_formatting_escaping_utf8/test.cpp +++ b/tests/std/tests/P2286R8_text_formatting_escaping_utf8/test.cpp @@ -21,15 +21,32 @@ void test_escaped_string() { assert(format("{:?}", "a\u0300") == "\"a\u0300\""); } -int main() { +template +void test_tuple_or_pair_escaping(TupleOrPair&& input) { + get<1>(input) = "hell\u00d6"; // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS + assert(format("{}", input) == "('*', \"hell\u00d6\")"); + assert(format("{:#^16}", input) == "#('*', \"hell\u00d6\")#"); + + get<1>(input) = "hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O + assert(format("{}", input) == "('*', \"hell\uff2f\")"); + assert(format("{:#^16}", input) == "('*', \"hell\uff2f\")#"); +} + +void run_test() { test_escaped_string(); + test_tuple_or_pair_escaping(make_pair('*', "")); + test_tuple_or_pair_escaping(make_tuple('*', "")); +} + +int main() { + run_test(); assert(setlocale(LC_ALL, ".1252") != nullptr); - test_escaped_string(); + run_test(); assert(setlocale(LC_ALL, ".932") != nullptr); - test_escaped_string(); + run_test(); assert(setlocale(LC_ALL, ".UTF-8") != nullptr); - test_escaped_string(); + run_test(); } diff --git a/tests/std/tests/P2286R8_text_formatting_tuple/test.cpp b/tests/std/tests/P2286R8_text_formatting_tuple/test.cpp index d2b89c1c74b..f00365ea87e 100644 --- a/tests/std/tests/P2286R8_text_formatting_tuple/test.cpp +++ b/tests/std/tests/P2286R8_text_formatting_tuple/test.cpp @@ -157,9 +157,16 @@ void test_escaping(TestFunction check, TupleOrPair&& input) { check(SV(R"(('\u{0}', ""))"), SV("{}"), input); // String - get<0>(input) = CharT('*'); - get<1>(input) = SV("hell\u00d6"); - check(SV("('*', \"hell\u00d6\")"), SV("{}"), input); + if constexpr (is_same_v) { + get<0>(input) = L'*'; + get<1>(input) = L"hell\u00d6"; // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS + check(L"('*', \"hell\u00d6\")"sv, L"{}"sv, input); + check(L"#('*', \"hell\u00d6\")#"sv, L"{:#^16}"sv, input); + + get<1>(input) = L"hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O + check(L"('*', \"hell\uff2f\")"sv, L"{}"sv, input); + check(L"('*', \"hell\uff2f\")#"sv, L"{:#^16}"sv, input); + } } //