From e97df46ae1b43fad38786a0f4645038d980087bb Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 15 Sep 2024 16:02:29 -0700 Subject: [PATCH] Cleanup type mapping --- include/fmt/base.h | 65 ++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 1aaa8fa0..606f4f6b 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -1100,6 +1100,13 @@ struct use_format_as< T, bool_constant>::value>> : std::true_type {}; +template +using use_formatter = + bool_constant<(std::is_class::value || std::is_enum::value || + std::is_union::value) && + !has_to_string_view::value && !is_named_arg::value && + !use_format_as::value>; + template constexpr auto has_const_formatter_impl(T*) -> decltype(formatter().format( @@ -1117,11 +1124,9 @@ constexpr auto has_const_formatter() -> bool { } struct unformattable {}; -struct unformattable_char : unformattable {}; -struct unformattable_pointer : unformattable {}; -// Maps formatting argument types to reduce the set of types we need to work -// with. Returns unformattable* on errors to be SFINAE-friendly. +// Maps formatting argument types to a smaller set. Returns unformattable* on +// errors to be SFINAE-friendly. template struct arg_mapper { static auto map(signed char) -> int; static auto map(unsigned char) -> unsigned; @@ -1147,7 +1152,7 @@ template struct arg_mapper { template ::value)> static auto map(T) -> conditional_t::value || std::is_same::value, - Char, unformattable_char>; + Char, unformattable>; static auto map(float) -> float; static auto map(double) -> double; @@ -1159,7 +1164,7 @@ template struct arg_mapper { FMT_ENABLE_IF(!std::is_pointer::value)> static auto map(const T&) -> conditional_t::value, basic_string_view, - unformattable_char>; + unformattable>; static auto map(void*) -> const void*; static auto map(const void*) -> const void*; @@ -1168,7 +1173,7 @@ template struct arg_mapper { static auto map(std::nullptr_t) -> const void*; template ::value || std::is_member_pointer::value)> - static auto map(const T&) -> unformattable_pointer; + static auto map(const T&) -> unformattable; template ::value)> static auto map(const T (&)[N]) -> const T (&)[N]; @@ -1182,25 +1187,12 @@ template struct arg_mapper { (std::is_constructible>::value && !std::is_const::value)> {}; - template ::value)> - static auto do_map(T& x) -> T&; - template ::value)> - static auto do_map(T&) -> unformattable; - - // is_fundamental is used to allow formatters for extended FP types. - template , - FMT_ENABLE_IF( - (std::is_class::value || std::is_enum::value || - std::is_union::value || std::is_fundamental::value) && - !has_to_string_view::value && !is_char::value && - !is_named_arg::value && !std::is_integral::value && - !use_format_as::value)> - static auto map(T& x) -> decltype(do_map(x)); + template >::value)> + static auto map(T&) + -> conditional_t::value, T&, unformattable>; template ::value)> static auto map(const T& named_arg) -> decltype(map(named_arg.value)); - - static auto map(...) -> unformattable; }; // detail:: is used to workaround a bug in MSVC 2017. @@ -2183,6 +2175,9 @@ template class value { template ::value || std::is_member_pointer::value)> value(const T&) { + // Formatting of arbitrary pointers is disallowed. If you want to format a + // pointer cast it to `void*` or `const void*`. In particular, this forbids + // formatting of `[const] volatile char*` printed as bool by iostreams. static_assert(sizeof(T) == 0, "formatting of non-void pointers is disallowed"); } @@ -2196,16 +2191,7 @@ template class value { template ::value)> value(const T& named_arg) : value(named_arg.value) {} - template > - using mappable = - bool_constant::value && - !std::is_pointer::value && !is_named_arg::value && - !use_format_as::value>; - - template < - typename T, - typename M = decltype(arg_mapper::map(std::declval())), - FMT_ENABLE_IF(std::is_same::value&& mappable::value)> + template >::value)> FMT_CONSTEXPR20 FMT_INLINE value(T&& x) : value(x, custom_tag()) {} FMT_ALWAYS_INLINE value(const named_arg_info* args, size_t size) @@ -2213,15 +2199,6 @@ template class value { private: template FMT_CONSTEXPR value(const T& x, custom_tag) { - // Formatting of arbitrary pointers is disallowed. If you want to format a - // pointer cast it to `void*` or `const void*`. In particular, this forbids - // formatting of `[const] volatile char*` printed as bool by iostreams. - enum { - formattable_pointer = !std::is_same::value - }; - static_assert(formattable_pointer, - "formatting of non-void pointers is disallowed"); - using value_type = remove_cvref_t; enum { formattable = !std::is_same::value }; @@ -2242,10 +2219,6 @@ template class value { if (!is_constant_evaluated()) custom.value = const_cast(&reinterpret_cast(x)); - // Get the formatter type through the context to allow different contexts - // have different extension points, e.g. `formatter` for `format` and - // `printf_formatter` for `printf`. - custom.format = format_custom>; }