diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | libs/kstd/kstd/bits/format/string.hpp | 8 | ||||
| -rw-r--r-- | libs/kstd/kstd/bits/format/vformat.cpp (renamed from libs/kstd/kstd/vformat.cpp) | 15 | ||||
| -rw-r--r-- | libs/kstd/kstd/bits/format/vformat.hpp | 41 | ||||
| -rw-r--r-- | libs/kstd/kstd/format | 36 | ||||
| -rw-r--r-- | libs/kstd/kstd/format.test.cpp | 68 |
6 files changed, 138 insertions, 32 deletions
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt index 5a957573..002fb548 100644 --- a/libs/kstd/CMakeLists.txt +++ b/libs/kstd/CMakeLists.txt @@ -18,7 +18,7 @@ add_library("kstd::lib" ALIAS "kstd") target_sources("kstd" PRIVATE "kstd/os/error.cpp" "kstd/mutex.cpp" - "kstd/vformat.cpp" + "kstd/bits/format/vformat.cpp" ) file(GLOB_RECURSE KSTD_HEADERS diff --git a/libs/kstd/kstd/bits/format/string.hpp b/libs/kstd/kstd/bits/format/string.hpp index e7e40886..a2b298d4 100644 --- a/libs/kstd/kstd/bits/format/string.hpp +++ b/libs/kstd/kstd/bits/format/string.hpp @@ -72,8 +72,7 @@ namespace kstd template<typename... Args> struct format_string { - template<std::size_t Size> - consteval format_string(char const (&str)[Size]) noexcept(false) // NOLINT + consteval format_string(std::string_view const & str) noexcept(false) : str_view{str} { using namespace bits::format; @@ -140,6 +139,11 @@ namespace kstd } } + template<std::size_t Size> + consteval format_string(char const (&str)[Size]) noexcept(false) // NOLINT + : format_string{std::string_view{str}} + {} + std::string_view str_view; }; diff --git a/libs/kstd/kstd/vformat.cpp b/libs/kstd/kstd/bits/format/vformat.cpp index b7c51218..1bf293a4 100644 --- a/libs/kstd/kstd/vformat.cpp +++ b/libs/kstd/kstd/bits/format/vformat.cpp @@ -206,4 +206,19 @@ namespace kstd::bits::format return std::move(m_result); } + auto size_recorder::push(std::string_view text) -> void + { + m_size += text.size(); + } + + auto size_recorder::push(char) -> void + { + ++m_size; + } + + auto size_recorder::size() const noexcept -> std::size_t + { + return m_size; + } + } // namespace kstd::bits::format
\ No newline at end of file diff --git a/libs/kstd/kstd/bits/format/vformat.hpp b/libs/kstd/kstd/bits/format/vformat.hpp index 994fae50..2db56d17 100644 --- a/libs/kstd/kstd/bits/format/vformat.hpp +++ b/libs/kstd/kstd/bits/format/vformat.hpp @@ -3,12 +3,13 @@ // IWYU pragma: private, include <kstd/format> +#include <kstd/bits/basic_string.hpp> #include <kstd/bits/format/args.hpp> #include <kstd/bits/format/output_buffer.hpp> #include <kstd/bits/format/string.hpp> -#include <kstd/string> #include <algorithm> +#include <cstddef> #include <iterator> #include <string_view> #include <type_traits> @@ -29,13 +30,25 @@ namespace kstd struct string_writer : output_buffer { - auto push(std::string_view text) -> void override; - auto push(char character) -> void override; + auto push(std::string_view text) -> void final; + auto push(char character) -> void final; - auto release() -> string &&; + auto release() -> basic_string<char> &&; private: - string m_result{}; + basic_string<char> m_result{}; + }; + + //! A buffer that merely records the size of the output written to it. + struct size_recorder : output_buffer + { + auto push(std::string_view text) -> void final; + auto push(char character) -> void final; + + [[nodiscard]] auto size() const noexcept -> std::size_t; + + private: + std::size_t m_size{}; }; template<std::output_iterator<char> Output> @@ -72,7 +85,8 @@ namespace kstd //! @param args The arguments for the format string. //! @return A new string containing the result of the format operation. template<typename... ArgumentTypes> - auto format(format_string<std::type_identity_t<ArgumentTypes>...> format, ArgumentTypes &&... args) -> string + auto format(format_string<std::type_identity_t<ArgumentTypes>...> format, ArgumentTypes &&... args) + -> basic_string<char> { auto buffer = bits::format::string_writer{}; bits::format::vformat_to(buffer, format.str_view, make_format_args(std::forward<ArgumentTypes>(args)...).args); @@ -94,6 +108,21 @@ namespace kstd return buffer.iterator(); } + //! Determine the number of characters required to format the format string with the given arguments. + //! + //! @param format The format string. + //! @param args The arguments for the format string. + //! @tparam ArgumentTypes The type of the format string arguments. + //! @return The number of characters required to format @p format with @p args + template<typename... ArgumentTypes> + auto formatted_size(format_string<std::type_identity_t<ArgumentTypes>...> format, ArgumentTypes &&... args) + -> std::size_t + { + auto buffer = bits::format::size_recorder{}; + bits::format::vformat_to(buffer, format.str_view, make_format_args(std::forward<ArgumentTypes>(args)...).args); + return buffer.size(); + } + } // namespace kstd #endif
\ No newline at end of file diff --git a/libs/kstd/kstd/format b/libs/kstd/kstd/format index e04b79a9..5ed798db 100644 --- a/libs/kstd/kstd/format +++ b/libs/kstd/kstd/format @@ -1,22 +1,24 @@ #ifndef KSTD_FORMAT_HPP #define KSTD_FORMAT_HPP -#include <kstd/bits/format/arg.hpp> // IWYU pragma: export -#include <kstd/bits/format/args.hpp> // IWYU pragma: export -#include <kstd/bits/format/context.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/bool.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/byte.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/char.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/cstring.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/integral.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/ordering.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/pointer.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/range.hpp> // IWYU pragma: export -#include <kstd/bits/format/formatter/string_view.hpp> // IWYU pragma: export -#include <kstd/bits/format/output_buffer.hpp> // IWYU pragma: export -#include <kstd/bits/format/parse_context.hpp> // IWYU pragma: export -#include <kstd/bits/format/string.hpp> // IWYU pragma: export -#include <kstd/bits/format/vformat.hpp> // IWYU pragma: export +// IWYU pragma: begin_exports +#include <kstd/bits/format/arg.hpp> +#include <kstd/bits/format/args.hpp> +#include <kstd/bits/format/context.hpp> +#include <kstd/bits/format/formatter.hpp> +#include <kstd/bits/format/formatter/bool.hpp> +#include <kstd/bits/format/formatter/byte.hpp> +#include <kstd/bits/format/formatter/char.hpp> +#include <kstd/bits/format/formatter/cstring.hpp> +#include <kstd/bits/format/formatter/integral.hpp> +#include <kstd/bits/format/formatter/ordering.hpp> +#include <kstd/bits/format/formatter/pointer.hpp> +#include <kstd/bits/format/formatter/range.hpp> +#include <kstd/bits/format/formatter/string_view.hpp> +#include <kstd/bits/format/output_buffer.hpp> +#include <kstd/bits/format/parse_context.hpp> +#include <kstd/bits/format/string.hpp> +#include <kstd/bits/format/vformat.hpp> +// IWYU pragma: end_exports #endif
\ No newline at end of file diff --git a/libs/kstd/kstd/format.test.cpp b/libs/kstd/kstd/format.test.cpp index 624779af..6126605f 100644 --- a/libs/kstd/kstd/format.test.cpp +++ b/libs/kstd/kstd/format.test.cpp @@ -4,14 +4,17 @@ #include <iterator> #include <sstream> +#include <string_view> + +using namespace std::string_view_literals; SCENARIO("Formatting to a new string", "[format]") { GIVEN("a format string without any placeholders") { - auto const & fmt = "This is a test"; + constexpr auto fmt = "This is a test"sv; - WHEN("calling format with without any arguments.") + WHEN("calling format without any arguments.") { auto result = kstd::format(fmt); @@ -34,7 +37,7 @@ SCENARIO("Formatting to a new string", "[format]") GIVEN("a format string with placeholders") { - auto const & fmt = "Here are some placeholders: {} {} {}"; + constexpr auto fmt = "Here are some placeholders: {} {} {}"sv; WHEN("calling format with the same number of arguments as there are placeholders") { @@ -64,9 +67,9 @@ SCENARIO("Formatting to an output iterator", "[format]") GIVEN("a format string without any placeholders") { - auto const & fmt = "This is a test"; + constexpr auto fmt = "This is a test"sv; - WHEN("calling format with without any arguments.") + WHEN("calling format without any arguments.") { kstd::format_to(std::ostream_iterator<char>{buffer}, fmt); @@ -89,7 +92,7 @@ SCENARIO("Formatting to an output iterator", "[format]") GIVEN("a format string with placeholders") { - auto const & fmt = "Here are some placeholders: {} {} {}"; + constexpr auto fmt = "Here are some placeholders: {} {} {}"sv; WHEN("calling format with the same number of arguments as there are placeholders") { @@ -111,4 +114,57 @@ SCENARIO("Formatting to an output iterator", "[format]") } } } +} + +SCENARIO("Determining formatted size") +{ + GIVEN("a format string without any placeholders") + { + constexpr auto fmt = "This is a test"sv; + + WHEN("calling formatted_size without any arguments") + { + auto const size = kstd::formatted_size(fmt); + + THEN("the result is equal to the length of the format string") + { + REQUIRE(size == fmt.size()); + } + } + + WHEN("calling format with additional arguments") + { + auto const size = kstd::formatted_size(fmt, 1, 2, 3); + + THEN("the result is equal to the length of the format string") + { + REQUIRE(size == fmt.size()); + } + } + } + + GIVEN("a format string with placeholders") + { + constexpr auto fmt = "Here are some placeholders: {} {} {}"sv; + + WHEN("calling format with the same number of arguments as there are placeholders") + { + auto result = kstd::formatted_size(fmt, 1, true, 'a'); + + THEN("the result is the formatted length") + { + REQUIRE(result == std::string_view{"Here are some placeholders: 1 true a"}.size()); + } + } + + WHEN("calling format with too many arguments") + { + auto result = kstd::formatted_size(fmt, 2, false, 'b', 4, 5, 6); + + THEN("the result is the formatted length") + { + REQUIRE(result == std::string_view{"Here are some placeholders: 2 false b"}.size()); + } + } + } }
\ No newline at end of file |
