From de4705f84d16324c9496d0833e09656bc5d0e5f4 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Sat, 1 Jul 2023 08:46:04 -0500 Subject: [PATCH] Trying to improve errors in the unformattable case (#3478) --- include/fmt/core.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/fmt/core.h b/include/fmt/core.h index 2323585b..ae80287e 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1548,6 +1548,11 @@ constexpr auto encode_types() -> unsigned long long { (encode_types() << packed_arg_bits); } +#if defined(__cpp_if_constexpr) +// This type is intentionally undefined, only used for errors +template struct type_is_unformattable_for; +#endif + template FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { using arg_type = remove_cvref_t().map(val))>; @@ -1565,6 +1570,11 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { "Formatting of non-void pointers is disallowed."); constexpr bool formattable = !std::is_same::value; +#if defined(__cpp_if_constexpr) + if constexpr (!formattable) { + type_is_unformattable_for _; + } +#endif static_assert( formattable, "Cannot format an argument. To make type T formattable provide a " @@ -2529,7 +2539,17 @@ FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) mapped_type_constant::value != type::custom_type, decltype(arg_mapper().map(std::declval())), typename strip_named_arg::type>; +#if defined(__cpp_if_constexpr) + if constexpr (std::is_default_constructible_v< + formatter>) { + return formatter().parse(ctx); + } else { + type_is_unformattable_for _; + return ctx.begin(); + } +#else return formatter().parse(ctx); +#endif } // Checks char specs and returns true iff the presentation type is char-like.