diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-13 16:18:00 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-13 16:18:00 +0200 |
| commit | 3795115641bf5c1d1a3d60313408ba462057ba18 (patch) | |
| tree | 8dd4baafe46561d64fd72ae086ebc2ddaa719816 | |
| parent | cd1dd2037cbe1d5f1362202d3127640406b468b8 (diff) | |
| download | teachos-3795115641bf5c1d1a3d60313408ba462057ba18.tar.xz teachos-3795115641bf5c1d1a3d60313408ba462057ba18.zip | |
kstd/format: add support for char formatting
| -rw-r--r-- | libs/kstd/include/kstd/bits/format/formatter/char.hpp | 94 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/format | 1 | ||||
| -rw-r--r-- | libs/kstd/tests/src/format.cpp | 8 |
3 files changed, 99 insertions, 4 deletions
diff --git a/libs/kstd/include/kstd/bits/format/formatter/char.hpp b/libs/kstd/include/kstd/bits/format/formatter/char.hpp new file mode 100644 index 0000000..ddfefe5 --- /dev/null +++ b/libs/kstd/include/kstd/bits/format/formatter/char.hpp @@ -0,0 +1,94 @@ +#ifndef KSTD_BITS_FORMAT_FORMATTER_CHAR_HPP +#define KSTD_BITS_FORMAT_FORMATTER_CHAR_HPP + +#include "../context.hpp" +#include "../error.hpp" +#include "../formatter.hpp" +#include "../parse_context.hpp" +#include "../specifiers.hpp" +#include "integral.hpp" + +#include <iterator> + +namespace kstd +{ + + template<> + struct formatter<char> : formatter<unsigned char> + { + bits::format::specifiers specifiers{}; + + constexpr auto parse(format_parse_context & context) -> format_parse_context::iterator + { + specifiers = bits::format::parse_format_specifiers(context); + + auto it = context.begin(); + auto const end = context.end(); + + if (specifiers.alternative_form || specifiers.zero_pad || specifiers.sign != bits::format::sign_mode::none) + { + bits::format::error("Invalid format specifiers for 'char'"); + } + + if (it != end && *it != '}') + { + if (*it == 'c' || *it == 'b' || *it == 'B' || *it == 'd' || *it == 'o' || *it == 'x' || *it == 'X') + { + specifiers.type = *it; + std::advance(it, 1); + } + else + { + bits::format::error("Invalid type specifier for char."); + } + } + + if (it != end && *it != '}') + { + bits::format::error("Missing terminating '}' in format string."); + } + + return it; + } + + auto format(char value, format_context & context) const -> void + { + if (specifiers.type == '\0' || specifiers.type == 'c') + { + auto final_width = 0uz; + + if (specifiers.mode == bits::format::width_mode::static_value) + { + final_width = specifiers.width_value; + } + else if (specifiers.mode == bits::format::width_mode::dynamic_argument_id) + { + auto const & arg = context.arg(specifiers.width_value); + final_width = bits::format::extrat_dynamic_width(arg); + } + + auto padding = + bits::format::calculate_format_padding(final_width, 1, specifiers.align, bits::format::alignment::left); + + for (auto i = 0uz; i < padding.left; ++i) + { + context.push(specifiers.fill); + } + + context.push(value); + + for (auto i = 0uz; i < padding.right; ++i) + { + context.push(specifiers.fill); + } + } + else + { + formatter<unsigned char>::format(static_cast<unsigned char>(value), context); + } + } + }; + +} // namespace kstd + +#endif
\ No newline at end of file diff --git a/libs/kstd/include/kstd/format b/libs/kstd/include/kstd/format index d11c221..047ea5c 100644 --- a/libs/kstd/include/kstd/format +++ b/libs/kstd/include/kstd/format @@ -7,6 +7,7 @@ #include "bits/format/formatter.hpp" // IWYU pragma: export #include "bits/format/formatter/bool.hpp" // IWYU pragma: export #include "bits/format/formatter/byte.hpp" // IWYU pragma: export +#include "bits/format/formatter/char.hpp" // IWYU pragma: export #include "bits/format/formatter/cstring.hpp" // IWYU pragma: export #include "bits/format/formatter/integral.hpp" // IWYU pragma: export #include "bits/format/formatter/ordering.hpp" // IWYU pragma: export diff --git a/libs/kstd/tests/src/format.cpp b/libs/kstd/tests/src/format.cpp index 4915e50..73c8102 100644 --- a/libs/kstd/tests/src/format.cpp +++ b/libs/kstd/tests/src/format.cpp @@ -40,21 +40,21 @@ SCENARIO("Formatting to a new string", "[format]") WHEN("calling format with the same number of arguments as there are placeholders") { - auto result = kstd::format(fmt, 1, true, -100); + auto result = kstd::format(fmt, 1, true, 'a'); THEN("the result is the formatted string") { - REQUIRE(result == "Here are some placeholders: 1 true -100"); + REQUIRE(result == "Here are some placeholders: 1 true a"); } } WHEN("calling format with too many arguments") { - auto result = kstd::format(fmt, 2, false, -200, 4, 5, 6); + auto result = kstd::format(fmt, 2, false, 'b', 4, 5, 6); THEN("the result is the formatted string") { - REQUIRE(result == "Here are some placeholders: 2 false -200"); + REQUIRE(result == "Here are some placeholders: 2 false b"); } } } |
