diff --git a/include/fmt/core.h b/include/fmt/core.h index b894399b..0dea4e98 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -492,6 +492,12 @@ struct convert_to_int : bool_constant::value && namespace internal { +// Specifies if T has an enabled formatter specialization. The type can be +// formattable even if it doesn't have a formatter e.g. via conversion. +template +using has_formatter = + std::is_constructible>; + /** A contiguous memory buffer with an optional growing ability. */ template class buffer { private: @@ -675,10 +681,6 @@ template struct custom_value { void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); }; -template -using is_formattable = - std::is_constructible>; - // A formatting argument value. template class value { public: @@ -727,7 +729,7 @@ template class value { // have different extension points, e.g. `formatter` for `format` and // `printf_formatter` for `printf`. custom.format = &format_custom_arg< - T, conditional_t::value, + T, conditional_t::value, typename Context::template formatter_type, internal::fallback_formatter>>; } @@ -875,7 +877,7 @@ inline init make_value(const T& val) { template ::value&& std::is_convertible< - T, int>::value&& is_formattable::value && + T, int>::value&& has_formatter::value && !std::is_same::value)> inline init make_value(const T& val) { return val; diff --git a/include/fmt/format.h b/include/fmt/format.h index 6bca25e4..fd12f99d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2179,7 +2179,7 @@ FMT_CONSTEXPR const typename ParseContext::char_type* parse_format_specs( ParseContext& ctx) { // GCC 7.2 requires initializer. typedef typename ParseContext::char_type char_type; - conditional_t>::value, + conditional_t>::value, formatter, internal::fallback_formatter> f; diff --git a/test/format-test.cc b/test/format-test.cc index 9832c8c7..d98c7791 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1877,7 +1877,7 @@ enum TestEnum { A }; TEST(FormatTest, Enum) { EXPECT_EQ("0", fmt::format("{}", A)); } TEST(FormatTest, FormatterNotSpecialized) { - EXPECT_FALSE((fmt::internal::is_formattable< + EXPECT_FALSE((fmt::internal::has_formatter< fmt::formatter, fmt::format_context>::value)); }