Trying to improve errors in the unformattable case.

This commit is contained in:
Barry Revzin 2023-06-04 12:28:00 -05:00
parent 60fd9941c0
commit b5bd6323fc

View File

@ -1539,12 +1539,18 @@ constexpr auto encode_types() -> unsigned long long {
(encode_types<Context, Args...>() << packed_arg_bits);
}
// This type is intentionally undefined, only used for errors
template <typename T, typename Char> struct type_is_unformattable_for;
template <bool PACKED, typename Context, typename T, FMT_ENABLE_IF(PACKED)>
FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value<Context> {
using arg_type = remove_cvref_t<decltype(arg_mapper<Context>().map(val))>;
constexpr bool formattable_char =
!std::is_same<arg_type, unformattable_char>::value;
if constexpr (not formattable_char) {
type_is_unformattable_for<T, typename Context::char_type> _;
}
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<Context> {
// formatting of `[const] volatile char*` printed as bool by iostreams.
constexpr bool formattable_pointer =
!std::is_same<arg_type, unformattable_pointer>::value;
if constexpr (not formattable_pointer) {
type_is_unformattable_for<T, typename Context::char_type> _;
}
static_assert(formattable_pointer,
"Formatting of non-void pointers is disallowed.");
constexpr bool formattable = !std::is_same<arg_type, unformattable>::value;
if constexpr (not formattable) {
type_is_unformattable_for<T, typename Context::char_type> _;
}
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<T, context>::value != type::custom_type,
decltype(arg_mapper<context>().map(std::declval<const T&>())),
typename strip_named_arg<T>::type>;
return formatter<mapped_type, char_type>().parse(ctx);
if constexpr (std::is_default_constructible_v<
formatter<mapped_type, char_type>>) {
return formatter<mapped_type, char_type>().parse(ctx);
} else {
type_is_unformattable_for<T, char_type> _;
return ctx.begin();
}
}
// Checks char specs and returns true iff the presentation type is char-like.