Skip to content

Commit b872c42

Browse files
authored
Measure display width in tuple formatter (#4631)
1 parent 8dc4faa commit b872c42

File tree

4 files changed

+50
-9
lines changed
  • stl/inc
  • tests/std/tests
    • P2286R8_text_formatting_escaping_legacy_text_encoding
    • P2286R8_text_formatting_escaping_utf8
    • P2286R8_text_formatting_tuple

4 files changed

+50
-9
lines changed

stl/inc/format

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3961,6 +3961,13 @@ _NODISCARD size_t formatted_size(const locale& _Loc, const wformat_string<_Types
39613961
_FMT_P2286_END
39623962

39633963
#if _HAS_CXX23
3964+
template <class _CharT>
3965+
_NODISCARD int _Measure_display_width(const basic_string_view<_CharT> _Value) {
3966+
int _Width = -1;
3967+
(void) _Measure_string_prefix(_Value, _Width);
3968+
return _Width;
3969+
}
3970+
39643971
enum class _Fmt_tuple_type : uint8_t { _None, _Key_value, _No_brackets };
39653972

39663973
template <class _CharT>
@@ -4127,8 +4134,9 @@ protected:
41274134
}(index_sequence_for<_ArgTypes...>{});
41284135
_STD _Copy_unchecked(_Closing_bracket._Unchecked_begin(), _Closing_bracket._Unchecked_end(), _Tmp_ctx.out());
41294136

4130-
return _STD _Write_aligned(_Fmt_ctx.out(), static_cast<int>(_Tmp_buf.size()), _Format_specs, _Fmt_align::_Left,
4131-
[&](typename _FormatContext::iterator _Out) {
4137+
const int _Width = _Measure_display_width<_CharT>(_Tmp_buf);
4138+
return _STD _Write_aligned(
4139+
_Fmt_ctx.out(), _Width, _Format_specs, _Fmt_align::_Left, [&](typename _FormatContext::iterator _Out) {
41324140
return _STD _Fmt_write(_STD move(_Out), basic_string_view<_CharT>{_Tmp_buf});
41334141
});
41344142
}

tests/std/tests/P2286R8_text_formatting_escaping_legacy_text_encoding/test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ void test_escaped_string() {
1717
assert(format("{:?}", "\x81\x40\x40\x81") == "\"\\u{3000}\x40\\x{81}\"");
1818
}
1919

20+
template <class TupleOrPair>
21+
void test_tuple_or_pair_escaping(TupleOrPair&& input) {
22+
get<1>(input) = "hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O
23+
assert(format("{}", input) == "('*', \"hell\uff2f\")");
24+
assert(format("{:#^16}", input) == "('*', \"hell\uff2f\")#");
25+
}
26+
2027
int main() {
2128
test_escaped_string();
29+
test_tuple_or_pair_escaping(make_pair('*', ""));
30+
test_tuple_or_pair_escaping(make_tuple('*', ""));
2231
}

tests/std/tests/P2286R8_text_formatting_escaping_utf8/test.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,32 @@ void test_escaped_string() {
2121
assert(format("{:?}", "a\u0300") == "\"a\u0300\"");
2222
}
2323

24-
int main() {
24+
template <class TupleOrPair>
25+
void test_tuple_or_pair_escaping(TupleOrPair&& input) {
26+
get<1>(input) = "hell\u00d6"; // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
27+
assert(format("{}", input) == "('*', \"hell\u00d6\")");
28+
assert(format("{:#^16}", input) == "#('*', \"hell\u00d6\")#");
29+
30+
get<1>(input) = "hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O
31+
assert(format("{}", input) == "('*', \"hell\uff2f\")");
32+
assert(format("{:#^16}", input) == "('*', \"hell\uff2f\")#");
33+
}
34+
35+
void run_test() {
2536
test_escaped_string();
37+
test_tuple_or_pair_escaping(make_pair('*', ""));
38+
test_tuple_or_pair_escaping(make_tuple('*', ""));
39+
}
40+
41+
int main() {
42+
run_test();
2643

2744
assert(setlocale(LC_ALL, ".1252") != nullptr);
28-
test_escaped_string();
45+
run_test();
2946

3047
assert(setlocale(LC_ALL, ".932") != nullptr);
31-
test_escaped_string();
48+
run_test();
3249

3350
assert(setlocale(LC_ALL, ".UTF-8") != nullptr);
34-
test_escaped_string();
51+
run_test();
3552
}

tests/std/tests/P2286R8_text_formatting_tuple/test.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,16 @@ void test_escaping(TestFunction check, TupleOrPair&& input) {
157157
check(SV(R"(('\u{0}', ""))"), SV("{}"), input);
158158

159159
// String
160-
get<0>(input) = CharT('*');
161-
get<1>(input) = SV("hell\u00d6");
162-
check(SV("('*', \"hell\u00d6\")"), SV("{}"), input);
160+
if constexpr (is_same_v<CharT, wchar_t>) {
161+
get<0>(input) = L'*';
162+
get<1>(input) = L"hell\u00d6"; // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
163+
check(L"('*', \"hell\u00d6\")"sv, L"{}"sv, input);
164+
check(L"#('*', \"hell\u00d6\")#"sv, L"{:#^16}"sv, input);
165+
166+
get<1>(input) = L"hell\uff2f"; // U+FF2F FULLWIDTH LATIN CAPITAL LETTER O
167+
check(L"('*', \"hell\uff2f\")"sv, L"{}"sv, input);
168+
check(L"('*', \"hell\uff2f\")#"sv, L"{:#^16}"sv, input);
169+
}
163170
}
164171

165172
//

0 commit comments

Comments
 (0)