From b5bd6323fcbe401e1fdda4ad550d87389d6a1efa Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Sun, 4 Jun 2023 12:28:00 -0500 Subject: [PATCH 1/5] Trying to improve errors in the unformattable case. --- include/fmt/core.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 4961310a311f..86dcd7a395ed 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1539,12 +1539,18 @@ constexpr auto encode_types() -> unsigned long long { (encode_types() << packed_arg_bits); } +// This type is intentionally undefined, only used for errors +template struct type_is_unformattable_for; + template FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { using arg_type = remove_cvref_t().map(val))>; constexpr bool formattable_char = !std::is_same::value; + if constexpr (not formattable_char) { + type_is_unformattable_for _; + } static_assert(formattable_char, "Mixing character types is disallowed."); // Formatting of arbitrary pointers is disallowed. If you want to format a @@ -1552,10 +1558,16 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { // formatting of `[const] volatile char*` printed as bool by iostreams. constexpr bool formattable_pointer = !std::is_same::value; + if constexpr (not formattable_pointer) { + type_is_unformattable_for _; + } static_assert(formattable_pointer, "Formatting of non-void pointers is disallowed."); constexpr bool formattable = !std::is_same::value; + if constexpr (not formattable) { + type_is_unformattable_for _; + } static_assert( formattable, "Cannot format an argument. To make type T formattable provide a " @@ -2520,7 +2532,13 @@ 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>; - return formatter().parse(ctx); + if constexpr (std::is_default_constructible_v< + formatter>) { + return formatter().parse(ctx); + } else { + type_is_unformattable_for _; + return ctx.begin(); + } } // Checks char specs and returns true iff the presentation type is char-like. From 805e84f6795d286019ed865016f2703239c6b9fe Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Mon, 19 Jun 2023 13:36:58 -0500 Subject: [PATCH 2/5] Adding guards around if constexpr --- include/fmt/core.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/fmt/core.h b/include/fmt/core.h index 86dcd7a395ed..5fe659ff96e4 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1539,8 +1539,10 @@ 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 { @@ -1548,9 +1550,11 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { constexpr bool formattable_char = !std::is_same::value; +#if defined(__cpp_if_constexpr) if constexpr (not formattable_char) { type_is_unformattable_for _; } +#endif static_assert(formattable_char, "Mixing character types is disallowed."); // Formatting of arbitrary pointers is disallowed. If you want to format a @@ -1558,16 +1562,20 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { // formatting of `[const] volatile char*` printed as bool by iostreams. constexpr bool formattable_pointer = !std::is_same::value; +#if defined(__cpp_if_constexpr) if constexpr (not formattable_pointer) { type_is_unformattable_for _; } +#endif static_assert(formattable_pointer, "Formatting of non-void pointers is disallowed."); constexpr bool formattable = !std::is_same::value; +#if defined(__cpp_if_constexpr) if constexpr (not formattable) { type_is_unformattable_for _; } +#endif static_assert( formattable, "Cannot format an argument. To make type T formattable provide a " @@ -2532,6 +2540,7 @@ 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); @@ -2539,6 +2548,9 @@ FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) 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. From 9b2ae5ec24ae4d1743328131edbee3eb3e9a8559 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Mon, 19 Jun 2023 13:55:58 -0500 Subject: [PATCH 3/5] Something something msvc. --- include/fmt/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 5fe659ff96e4..46354241a37a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1551,7 +1551,7 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { constexpr bool formattable_char = !std::is_same::value; #if defined(__cpp_if_constexpr) - if constexpr (not formattable_char) { + if constexpr (!formattable_char) { type_is_unformattable_for _; } #endif From 422181fca88ae0fecf107976ed9f2e444cb7a67c Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Mon, 19 Jun 2023 14:34:16 -0500 Subject: [PATCH 4/5] Something something msvc. --- include/fmt/core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 46354241a37a..e30fba865b87 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1563,7 +1563,7 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { constexpr bool formattable_pointer = !std::is_same::value; #if defined(__cpp_if_constexpr) - if constexpr (not formattable_pointer) { + if constexpr (!formattable_pointer) { type_is_unformattable_for _; } #endif @@ -1572,7 +1572,7 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { constexpr bool formattable = !std::is_same::value; #if defined(__cpp_if_constexpr) - if constexpr (not formattable) { + if constexpr (!formattable) { type_is_unformattable_for _; } #endif From 1323cd4ea2e0d4f6c734d7ae75c3d8de0aeba638 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Sun, 25 Jun 2023 10:36:43 -0500 Subject: [PATCH 5/5] Removing these two --- include/fmt/core.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index e30fba865b87..65fe9f9889c9 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1550,11 +1550,6 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { constexpr bool formattable_char = !std::is_same::value; -#if defined(__cpp_if_constexpr) - if constexpr (!formattable_char) { - type_is_unformattable_for _; - } -#endif static_assert(formattable_char, "Mixing character types is disallowed."); // Formatting of arbitrary pointers is disallowed. If you want to format a @@ -1562,11 +1557,6 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value { // formatting of `[const] volatile char*` printed as bool by iostreams. constexpr bool formattable_pointer = !std::is_same::value; -#if defined(__cpp_if_constexpr) - if constexpr (!formattable_pointer) { - type_is_unformattable_for _; - } -#endif static_assert(formattable_pointer, "Formatting of non-void pointers is disallowed.");