Use typeid() only if it's available

On MSVC it is always available, otherwise it depends on whether
RTTI is enabled.
This commit is contained in:
Dana Jansens
2023-05-30 21:38:39 -04:00
committed by Victor Zverovich
parent 61fb3a15ff
commit 179c7e5a66

View File

@ -44,6 +44,24 @@
# endif # endif
#endif #endif
// Check if typeid is available.
#ifndef FMT_USE_TYPEID
// In MSVC, typeid() is available with or without RTTI.
# if defined(_MSC_VER)
# define FMT_USE_TYPEID 1
# elif defined(__RTTI) // EDG compilers.
# define FMT_USE_TYPEID 1
# elif defined(__INTEL_RTTI__) // Intel compiler.
# define FMT_USE_TYPEID 1
# elif defined(__GXX_RTTI) // G++.
# define FMT_USE_TYPEID 1
# elif FMT_HAS_FEATURE(cxx_rtti) // Clang.
# define FMT_USE_TYPEID 1
# else
# define FMT_USE_TYPEID 0
# endif
#endif
#ifdef __cpp_lib_filesystem #ifdef __cpp_lib_filesystem
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
@ -274,7 +292,7 @@ struct formatter<
if (it == end || *it == '}') return it; if (it == end || *it == '}') return it;
if (*it == 't') { if (*it == 't') {
++it; ++it;
with_typename_ = true; with_typename_ = FMT_USE_TYPEID != 0;
} }
return it; return it;
} }
@ -287,8 +305,9 @@ struct formatter<
if (!with_typename_) if (!with_typename_)
return detail::write_bytes(out, string_view(ex.what()), spec); return detail::write_bytes(out, string_view(ex.what()), spec);
#if FMT_USE_TYPEID
const std::type_info& ti = typeid(ex); const std::type_info& ti = typeid(ex);
#ifdef FMT_HAS_ABI_CXA_DEMANGLE # ifdef FMT_HAS_ABI_CXA_DEMANGLE
int status = 0; int status = 0;
std::size_t size = 0; std::size_t size = 0;
std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr( std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
@ -327,21 +346,22 @@ struct formatter<
demangled_name_view = string_view(ti.name()); demangled_name_view = string_view(ti.name());
} }
out = detail::write_bytes(out, demangled_name_view, spec); out = detail::write_bytes(out, demangled_name_view, spec);
#elif FMT_MSC_VERSION # elif FMT_MSC_VERSION
string_view demangled_name_view(ti.name()); string_view demangled_name_view(ti.name());
if (demangled_name_view.starts_with("class ")) if (demangled_name_view.starts_with("class "))
demangled_name_view.remove_prefix(6); demangled_name_view.remove_prefix(6);
else if (demangled_name_view.starts_with("struct ")) else if (demangled_name_view.starts_with("struct "))
demangled_name_view.remove_prefix(7); demangled_name_view.remove_prefix(7);
out = detail::write_bytes(out, demangled_name_view, spec); out = detail::write_bytes(out, demangled_name_view, spec);
#else # else
out = detail::write_bytes(out, string_view(ti.name()), spec); out = detail::write_bytes(out, string_view(ti.name()), spec);
#endif # endif
out = detail::write<Char>(out, Char(':')); out = detail::write<Char>(out, Char(':'));
out = detail::write<Char>(out, Char(' ')); out = detail::write<Char>(out, Char(' '));
out = detail::write_bytes(out, string_view(ex.what()), spec); out = detail::write_bytes(out, string_view(ex.what()), spec);
return out; return out;
#endif
} }
}; };
FMT_END_NAMESPACE FMT_END_NAMESPACE