Skip to content

Commit

Permalink
AK+Format: Add support for integer to character casts.
Browse files Browse the repository at this point in the history
Now the following is possible:

    outf("{:c}", 75); // K
  • Loading branch information
asynts authored and awesomekling committed Sep 29, 2020
1 parent f221a95 commit 1175ecf
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
45 changes: 42 additions & 3 deletions AK/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions AK/Tests/TestFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 1175ecf

Please sign in to comment.