From cb58b689ca66132e72e463f11825ca51acef4dc7 Mon Sep 17 00:00:00 2001 From: Matthias Moulin Date: Sat, 25 May 2024 17:51:30 +0200 Subject: [PATCH] Added std::type_info formatter * Added std::type_info formatter; * Reused std::type_info formatter in std::exception formatters; * Updated MSVC std::type_info outputting to exclude all class, struct and enum occurences. --- include/fmt/std.h | 103 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 31 deletions(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 821d9fbea1d5a..c5e449e3f321a 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -15,6 +15,7 @@ # include # include # include +# include # include # include # include @@ -416,36 +417,34 @@ template struct formatter { } }; -FMT_EXPORT -template -struct formatter< - T, Char, // DEPRECATED! Mixing code unit types. - typename std::enable_if::value>::type> { - private: - bool with_typename_ = false; +#if FMT_USE_RTTI +namespace details { +template +inline void remove_all_substrings( + std::basic_string& src, + type_identity_t> pattern) { + const auto pattern_length = pattern.size(); + for (auto i = src.find(pattern.data(), 0, pattern_length); + i != std::basic_string::npos; + i = src.find(pattern.data(), 0, pattern_length)) + src.erase(i, pattern_length); +} +} // namespace details +FMT_EXPORT +template +struct formatter { public: FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(); - auto end = ctx.end(); - if (it == end || *it == '}') return it; - if (*it == 't') { - ++it; - with_typename_ = FMT_USE_RTTI != 0; - } - return it; + return ctx.begin(); } template - auto format(const std::exception& ex, Context& ctx) const + auto format(const std::type_info& ti, Context& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); - if (!with_typename_) - return detail::write_bytes(out, string_view(ex.what())); - -#if FMT_USE_RTTI - const std::type_info& ti = typeid(ex); # ifdef FMT_HAS_ABI_CXA_DEMANGLE int status = 0; std::size_t size = 0; @@ -484,22 +483,64 @@ struct formatter< } else { demangled_name_view = string_view(ti.name()); } - out = detail::write_bytes(out, demangled_name_view); + return detail::write_bytes(out, demangled_name_view); # elif FMT_MSC_VERSION - string_view demangled_name_view(ti.name()); - if (demangled_name_view.starts_with("class ")) - demangled_name_view.remove_prefix(6); - else if (demangled_name_view.starts_with("struct ")) - demangled_name_view.remove_prefix(7); - out = detail::write_bytes(out, demangled_name_view); + std::basic_string demangled_name(ti.name()); + auto class_space = + detail::string_literal{}; + auto enum_space = detail::string_literal{}; + auto struct_space = + detail::string_literal{}; + auto union_space = + detail::string_literal{}; + details::remove_all_substrings(demangled_name, class_space); + details::remove_all_substrings(demangled_name, enum_space); + details::remove_all_substrings(demangled_name, struct_space); + details::remove_all_substrings(demangled_name, union_space); + return detail::write_bytes(out, demangled_name); # else - out = detail::write_bytes(out, string_view(ti.name()) - }); + return detail::write_bytes(out, string_view(ti.name())); # endif + } +}; +#endif + +FMT_EXPORT +template +struct formatter< + T, Char, // DEPRECATED! Mixing code unit types. + typename std::enable_if::value>::type> { + private: + bool with_typename_ = false; + + public: + FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) + -> decltype(ctx.begin()) { + auto it = ctx.begin(); + auto end = ctx.end(); + if (it == end || *it == '}') return it; + if (*it == 't') { + ++it; + with_typename_ = FMT_USE_RTTI != 0; + } + return it; + } + + template + auto format(const std::exception& ex, Context& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + if (!with_typename_) + return detail::write_bytes(out, string_view(ex.what())); + +#if FMT_USE_RTTI + const std::type_info& ti = typeid(ex); + auto format_imag = detail::string_literal{}; + out = fmt::format_to(out, basic_string_view(format_imag), ti); +#endif *out++ = ':'; *out++ = ' '; return detail::write_bytes(out, string_view(ex.what())); -#endif } };