Skip to content

Commit

Permalink
Added std::type_info formatter
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
matt77hias committed May 25, 2024
1 parent 1768bf9 commit 0ade017
Showing 1 changed file with 63 additions and 34 deletions.
97 changes: 63 additions & 34 deletions include/fmt/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# include <cstdlib>
# include <exception>
# include <memory>
# include <string>
# include <thread>
# include <type_traits>
# include <typeinfo>
Expand Down Expand Up @@ -416,36 +417,33 @@ template <typename Char> struct formatter<std::error_code, Char> {
}
};

FMT_EXPORT
template <typename T, typename Char>
struct formatter<
T, Char, // DEPRECATED! Mixing code unit types.
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
private:
bool with_typename_ = false;
#if FMT_USE_RTTI
namespace details {
template <typename Char>
inline void remove_all_substrings(
std::basic_string<Char>& src,
std::type_identity_t<std::basic_string_view<Char>> pattern) {
const auto pattern_length = pattern.length();
for (auto i = src.find(pattern); i != std::basic_string<Char>::npos;
i = src.find(pattern))
src.erase(i, pattern_length);
}
} // namespace details

FMT_EXPORT
template <typename Char>
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
> {
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& 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 <typename Context>
auto format(const std::exception& ex, Context& ctx) const
-> decltype(ctx.out()) {
auto format(const std::type_info& ti,
Context& ctx) const -> decltype(ctx.out()) {
auto out = ctx.out();
if (!with_typename_)
return detail::write_bytes<Char>(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;
Expand Down Expand Up @@ -484,21 +482,52 @@ struct formatter<
} else {
demangled_name_view = string_view(ti.name());
}
out = detail::write_bytes<Char>(out, demangled_name_view);
return detail::write_bytes<Char>(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<Char>(out, demangled_name_view);
std::basic_string<Char> demangled_name(ti.name());
details::remove_all_substrings(demangled_name, "class ");
details::remove_all_substrings(demangled_name, "enum ");
details::remove_all_substrings(demangled_name, "struct ");
return detail::write_bytes<Char>(out, demangled_name);
# else
out = detail::write_bytes<Char>(out, string_view(ti.name())
});
return detail::write_bytes<Char>(out, string_view(ti.name()));
# endif
*out++ = ':';
*out++ = ' ';
return detail::write_bytes<Char>(out, string_view(ex.what()));
}
};
#endif

FMT_EXPORT
template <typename T, typename Char>
struct formatter<
T, Char, // DEPRECATED! Mixing code unit types.
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
private:
bool with_typename_ = false;

public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& 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 <typename Context>
auto format(const std::exception& ex, Context& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
if (!with_typename_)
return detail::write_bytes<Char>(out, string_view(ex.what()));

#if FMT_USE_RTTI
const std::type_info& ti = typeid(ex);
auto format_imag = detail::string_literal<Char, '{', '}'>{};
return fmt::format_to(out, basic_string_view<Char>(format_imag), ti);
#endif
}
};
Expand Down

0 comments on commit 0ade017

Please sign in to comment.