diff --git a/include/fmt/core.h b/include/fmt/core.h index 4d83df79..0fa70208 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1282,6 +1282,15 @@ inline auto format_as(std::byte b) -> unsigned char { } #endif +template struct has_format_as { + template ::value&& std::is_integral::value)> + static auto check(U*) -> std::true_type; + static auto check(...) -> std::false_type; + + enum { value = decltype(check(static_cast(nullptr)))::value }; +}; + // Maps formatting arguments to core types. // arg_mapper reports errors by returning unformattable instead of using // static_assert because it's used in the is_formattable trait. @@ -1436,11 +1445,10 @@ template struct arg_mapper { return map(static_cast>(val)); } - template ::value&& std::is_integral::value)> + template ::value && + !has_formatter::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) - -> decltype(std::declval().map(U())) { - static_assert(!has_formatter::value, ""); + -> decltype(std::declval().map(format_as(T()))) { return map(format_as(val)); } @@ -1470,6 +1478,7 @@ template struct arg_mapper { template , FMT_ENABLE_IF(!is_string::value && !is_char::value && !std::is_array::value && + !has_format_as::value && (has_formatter::value || has_fallback_formatter::value))> FMT_CONSTEXPR FMT_INLINE auto map(T&& val)