From b23be10416dfe3c803e58a765c941e65b39c7216 Mon Sep 17 00:00:00 2001 From: Roberto Rossini <71787608+robomics@users.noreply.github.com> Date: Fri, 2 Jun 2023 22:26:22 +0200 Subject: [PATCH] Implement format_parse_context::starts_with() Add method to check whether the format string starts with a given prefix. --- include/fmt/core.h | 14 ++++++++++++++ test/args-test.cc | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 4961310a..83adfe2a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -675,6 +675,20 @@ template class basic_format_parse_context { */ constexpr auto end() const noexcept -> iterator { return format_str_.end(); } + /** + * Checks whether the format string starts with the given prefix + */ + constexpr bool starts_with(iterator prefix) const noexcept { + auto first = begin(); + auto last = end(); + while (first != last && *prefix != '\0') { + if (*prefix++ != *first++) { + return false; + } + } + return *prefix == '\0'; + } + /** Advances the begin iterator to ``it``. */ FMT_CONSTEXPR void advance_to(iterator it) { format_str_.remove_prefix(detail::to_unsigned(it - begin())); diff --git a/test/args-test.cc b/test/args-test.cc index 3ab31335..4ffd3d78 100644 --- a/test/args-test.cc +++ b/test/args-test.cc @@ -38,12 +38,23 @@ struct custom_type { FMT_BEGIN_NAMESPACE template <> struct formatter { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { + private: + bool hex = false; + + public: + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + if (ctx.starts_with("hex")) { + hex = true; + return ctx.begin() + 3; + } return ctx.begin(); } template auto format(const custom_type& p, FormatContext& ctx) -> decltype(ctx.out()) { + if (hex) { + return fmt::format_to(ctx.out(), "cust={:x}", p.i); + } return fmt::format_to(ctx.out(), "cust={}", p.i); } }; @@ -57,9 +68,9 @@ TEST(args_test, custom_format) { store.push_back(c); ++c.i; store.push_back(std::cref(c)); - ++c.i; - auto result = fmt::vformat("{} and {} and {}", store); - EXPECT_EQ("cust=0 and cust=1 and cust=3", result); + c.i = 15; + auto result = fmt::vformat("{} and {} and {:hex}", store); + EXPECT_EQ("cust=0 and cust=1 and cust=f", result); } struct to_stringable {