Closed matt77hias closed 1 month ago
Ok still WIP in order to support wchar_t
. Ignore for now, but please leave it open so I can borrow the CI.
Update: removed union occurrences as well for MSVC
I think formatting std::type_info
should not change the output in MSVC. Removing all substrings may distort the result.
Before your changes, std::exception
formatting used minimal additional memory allocations (only for Itanium ABI).. I think it makes sense to keep this behavior.
I think formatting std::type_info should not change the output in MSVC. Removing all substrings may distort the result.
Note that prior to my changes, the class
or struct
prefix was already removed. Removing just these prefixes is somewhat arbitrary:
std::exception
);std::exception
). For example, typeid(std::vector<Foo>)
would be formatted as std::vector<class Foo,...>
(ignoring the allocator for easier discussion), while typeid(std::vector<Foo>::value_type)
would be formatted as just Foo
.Before your changes, std::exception formatting used minimal additional memory allocations (only for Itanium ABI).. I think it makes sense to keep this behavior.
I think we can output the characters one by one while jumping over the occurrences instead of using a std::basic_string
.
I do wonder whether I could erronously strip part of the actual identifier, instead of language keywords. All of the patterns do contain a space character that should prevent this. MSVC does not seem to use spaces before and after ,
, <
~and >
~. But that is all speculative of me.
Suggested changes
Create function:
namespace detail {
template <typename Char, typename OutputIt>
auto write_demangled_name(OutputIt out,
std::type_info& ti) -> OutputIt {
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
int status = 0;
std::size_t size = 0;
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
string_view demangled_name_view;
if (demangled_name_ptr) {
demangled_name_view = demangled_name_ptr.get();
// Normalization of stdlib inline namespace names.
// libc++ inline namespaces.
// std::__1::* -> std::*
// std::__1::__fs::* -> std::*
// libstdc++ inline namespaces.
// std::__cxx11::* -> std::*
// std::filesystem::__cxx11::* -> std::filesystem::*
if (demangled_name_view.starts_with("std::")) {
char* begin = demangled_name_ptr.get();
char* to = begin + 5; // std::
for (char *from = to, *end = begin + demangled_name_view.size();
from < end;) {
// This is safe, because demangled_name is NUL-terminated.
if (from[0] == '_' && from[1] == '_') {
char* next = from + 1;
while (next < end && *next != ':') next++;
if (next[0] == ':' && next[1] == ':') {
from = next + 2;
continue;
}
}
*to++ = *from++;
}
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
}
} else {
demangled_name_view = string_view(ti.name());
}
return detail::write_bytes<Char>(out, demangled_name_view);
# elif FMT_MSC_VERSION
std::string 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 ");
details::remove_all_substrings(demangled_name, "union ");
return detail::write_bytes<Char>(out, demangled_name);
# else
return detail::write_bytes<Char>(out, string_view(ti.name()));
# endif
}
}
and reuse it in formatters.
We don't need to use detail::string_literal
and std::basic_string<Char>
since std::type_info::name()
always returns const char *
write_demangled_name
function as suggested (but for const std::type_info&
);std::string
for MSVC;DynamicVector<int,GlobalMemoryAllocator<1>>
instead of DynamicVector<int,GlobalMemoryAllocator<1> >
;Out of scope improvements:
basic_string_view::size_type
, basic_string_view::front
, basic_string_view::substr
(which do not exist as of writing);<
or before >
to match style preferences.LGTM
It is actually implicitly tested already via the exception formatter.
But I can add another one. I'll reuse one of the exceptions because even something as simple as int
outputs something different on Clang and GCC.