Measure display width in tuple formatter (#4631)

This commit is contained in:
S. B. Tam 2024-05-21 06:32:50 +08:00 коммит произвёл GitHub
Родитель 8dc4faadaf
Коммит b872c42096
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 50 добавлений и 9 удалений

Просмотреть файл

@ -3961,6 +3961,13 @@ _NODISCARD size_t formatted_size(const locale& _Loc, const wformat_string<_Types
_FMT_P2286_END
#if _HAS_CXX23
template <class _CharT>
_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 <class _CharT>
@ -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<int>(_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});
});
}

Просмотреть файл

@ -17,6 +17,15 @@ void test_escaped_string() {
assert(format("{:?}", "\x81\x40\x40\x81") == "\"\\u{3000}\x40\\x{81}\"");
}
template <class TupleOrPair>
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('*', ""));
}

Просмотреть файл

@ -21,15 +21,32 @@ void test_escaped_string() {
assert(format("{:?}", "a\u0300") == "\"a\u0300\"");
}
int main() {
template <class TupleOrPair>
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();
}

Просмотреть файл

@ -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<CharT, wchar_t>) {
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);
}
}
//