From 2d3ba32e79588896fdd82272e93391547a7a3a2c Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 8 Sep 2024 09:17:59 -0700 Subject: [PATCH] Improve debug codegen --- include/fmt/base.h | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 9a51cf5a..bc6abaa4 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2812,11 +2812,8 @@ template struct runtime_format_string { inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; } /// A compile-time format string. -template class fstring { +template struct fstring { private: - const Char* str_; - size_t size_; - static constexpr int num_static_named_args = detail::count_static_named_args(); @@ -2827,12 +2824,12 @@ template class fstring { using arg_pack = detail::arg_pack; public: + basic_string_view str; using t = fstring; // Reports a compile-time error if S is not a valid format string for T. template - FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const Char (&s)[N]) - : str_(s), size_(N - 1) { + FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const Char (&s)[N]) : str(s, N - 1) { using namespace detail; static_assert(count<(std::is_base_of>::value && std::is_reference::value)...>() == 0, @@ -2847,10 +2844,7 @@ template class fstring { template >::value)> - FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) { - auto sv = basic_string_view(s); - str_ = sv.data(); - size_ = sv.size(); + FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) { if (FMT_USE_CONSTEVAL) detail::parse_format_string(s, checker(s, arg_pack())); #ifdef FMT_ENFORCE_COMPILE_STRING @@ -2862,21 +2856,19 @@ template class fstring { template ::value&& std::is_same::value)> - FMT_ALWAYS_INLINE fstring(const S&) { + FMT_ALWAYS_INLINE fstring(const S&) : str(S()) { FMT_CONSTEXPR auto sv = basic_string_view(S()); - str_ = sv.data(); - size_ = sv.size(); FMT_CONSTEXPR int ignore = (parse_format_string(sv, checker(sv, arg_pack())), 0); detail::ignore_unused(ignore); } - fstring(runtime_format_string fmt) - : str_(fmt.str.data()), size_(fmt.str.size()) {} + fstring(runtime_format_string fmt) : str(fmt.str) {} - FMT_ALWAYS_INLINE operator basic_string_view() const { - return {str_, size_}; + // Returning by reference generates better code in debug mode. + FMT_ALWAYS_INLINE operator const basic_string_view&() const { + return str; } - auto get() const -> basic_string_view { return {str_, size_}; } + auto get() const -> basic_string_view { return str; } }; template using format_string = typename fstring::t; @@ -3023,7 +3015,7 @@ auto vformat_to(char (&out)[N], string_view fmt, format_args args) template FMT_INLINE auto format_to(char (&out)[N], format_string fmt, T&&... args) -> format_to_result { - auto result = vformat_to_n(out, N, fmt, vargs{{args...}}); + auto result = vformat_to_n(out, N, fmt.str, vargs{{args...}}); return {result.out, result.size > N}; } @@ -3032,7 +3024,7 @@ template FMT_NODISCARD FMT_INLINE auto formatted_size(format_string fmt, T&&... args) -> size_t { auto buf = detail::counting_buffer<>(); - detail::vformat_to(buf, fmt, vargs{{args...}}, {}); + detail::vformat_to(buf, fmt.str, vargs{{args...}}, {}); return buf.count(); } @@ -3054,7 +3046,7 @@ FMT_INLINE void print(format_string fmt, T&&... args) { fmt::vargs vargs = {{args...}}; if (!FMT_USE_UTF8) return detail::vprint_mojibake(stdout, fmt, vargs, false); return detail::is_locking() ? vprint_buffered(stdout, fmt, vargs) - : vprint(fmt, vargs); + : vprint(fmt.str, vargs); } /** @@ -3070,7 +3062,7 @@ FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { fmt::vargs vargs = {{args...}}; if (!FMT_USE_UTF8) return detail::vprint_mojibake(f, fmt, vargs, false); return detail::is_locking() ? vprint_buffered(f, fmt, vargs) - : vprint(f, fmt, vargs); + : vprint(f, fmt.str, vargs); } /// Formats `args` according to specifications in `fmt` and writes the output