diff options
author | asynts <asynts@gmail.com> | 2020-09-29 14:07:39 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-09-29 16:14:58 +0200 |
commit | 1175ecf1dd520262dbb383decedae2cdebfbd0cc (patch) | |
tree | 8600433dd8bd8fb8818be2339f5d834097d6565a | |
parent | f221a95a7177716335f94cb0ac22b3649d7fbbc5 (diff) | |
download | serenity-1175ecf1dd520262dbb383decedae2cdebfbd0cc.zip |
AK+Format: Add support for integer to character casts.
Now the following is possible:
outf("{:c}", 75); // K
-rw-r--r-- | AK/Format.cpp | 45 | ||||
-rw-r--r-- | AK/Tests/TestFormat.cpp | 6 |
2 files changed, 48 insertions, 3 deletions
diff --git a/AK/Format.cpp b/AK/Format.cpp index a72c0874a0..e09a160d10 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -366,10 +366,8 @@ void Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type>::format(StringB { if (m_precision != value_not_set) ASSERT_NOT_REACHED(); - if (m_mode == Mode::Character) - TODO(); - u8 base; + u8 base = 0; bool upper_case = false; if (m_mode == Mode::Binary) { base = 2; @@ -385,12 +383,53 @@ void Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type>::format(StringB } else if (m_mode == Mode::HexadecimalUppercase) { base = 16; upper_case = true; + } else if (m_mode == Mode::Character) { + // special case } else { ASSERT_NOT_REACHED(); } auto width = decode_value(m_width, context); + const auto put_padding = [&](size_t amount, char fill) { + for (size_t i = 0; i < amount; ++i) + builder.append(fill); + }; + + if (m_mode == Mode::Character) { + // FIXME: We just support ASCII for now, in the future maybe unicode? + ASSERT(value >= 0 && value <= 127); + + const size_t used_by_value = 1; + const auto used_by_padding = width < used_by_value ? 0 : width - used_by_value; + + if (m_align == Align::Left || m_align == Align::Default) { + const auto used_by_right_padding = used_by_padding; + + builder.append(static_cast<char>(value)); + put_padding(used_by_right_padding, m_fill); + return; + } + if (m_align == Align::Center) { + const auto used_by_left_padding = used_by_padding / 2; + const auto used_by_right_padding = ceil_div<size_t, size_t>(used_by_padding, 2); + + put_padding(used_by_left_padding, m_fill); + builder.append(static_cast<char>(value)); + put_padding(used_by_right_padding, m_fill); + return; + } + if (m_align == Align::Right) { + const auto used_by_left_padding = used_by_padding; + + put_padding(used_by_left_padding, m_fill); + builder.append(static_cast<char>(value)); + return; + } + + ASSERT_NOT_REACHED(); + } + PrintfImplementation::Align align; if (m_align == Align::Left) align = PrintfImplementation::Align::Left; diff --git a/AK/Tests/TestFormat.cpp b/AK/Tests/TestFormat.cpp index 18994250fd..fa26f0caf2 100644 --- a/AK/Tests/TestFormat.cpp +++ b/AK/Tests/TestFormat.cpp @@ -130,4 +130,10 @@ TEST_CASE(complex_string_specifiers) EXPECT_EQ(String::formatted("{:^9}", "abcd"), " abcd "); } +TEST_CASE(cast_integer_to_character) +{ + EXPECT_EQ(String::formatted("{:c}", static_cast<int>('a')), "a"); + EXPECT_EQ(String::formatted("{:c}", static_cast<unsigned int>('f')), "f"); +} + TEST_MAIN(Format) |