From f6ac897b724538513bef320666bcf8207f5e15a8 Mon Sep 17 00:00:00 2001 From: Aamr El Kazdadi Date: Sun, 8 Dec 2019 03:46:55 +0100 Subject: [PATCH] Improve error reporting --- include/fmt/core.h | 51 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 1c6c855d..fa9cda91 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -809,7 +809,9 @@ template class value { private: // Formats an argument of a custom type, such as a user-defined class. - template + template ::value || + has_fallback_formatter::value)> static void format_custom_arg( const void* arg, basic_format_parse_context& parse_ctx, Context& ctx) { @@ -817,6 +819,16 @@ template class value { parse_ctx.advance_to(f.parse(parse_ctx)); ctx.advance_to(f.format(*static_cast(arg), ctx)); } + template ::value && + !has_fallback_formatter::value)> + static void format_custom_arg( + const void* arg, basic_format_parse_context& parse_ctx, + Context& ctx) { + (void)arg; + (void)parse_ctx; + (void)ctx; + } }; template @@ -828,6 +840,14 @@ enum { long_short = sizeof(long) == sizeof(int) }; using long_type = conditional_t; using ulong_type = conditional_t; +template struct is_convertible_to_any {}; +template +struct is_convertible_to_any : std::false_type {}; +template +struct is_convertible_to_any + : conditional_t::value, std::true_type, + is_convertible_to_any> {}; + // Maps formatting arguments to core types. template struct arg_mapper { using char_type = typename Context::char_type; @@ -878,8 +898,7 @@ template struct arg_mapper { FMT_ENABLE_IF( std::is_constructible, T>::value && !std::is_constructible, T>::value && - !is_string::value && - !has_formatter::value && + !is_string::value && !has_formatter::value && !has_fallback_formatter::value)> FMT_CONSTEXPR basic_string_view map(const T& val) { return std_string_view(val); @@ -923,6 +942,32 @@ template struct arg_mapper { return val; } + template < + typename T, + FMT_ENABLE_IF( + !is_convertible_to_any< + const T&, signed char, unsigned char, short, unsigned short, int, + unsigned, long, unsigned long, long long, unsigned long long, + int128_t, uint128_t, bool, float, double, long double, char_type*, + const char_type*, const char*, const signed char*, + const unsigned char*, void*, const void*, + std::nullptr_t>::value && + !std::is_constructible, T>::value && + !std::is_constructible, T>::value && + !is_string::value && !is_char::value && + !std::is_enum::value && !has_formatter::value && + !has_fallback_formatter::value)> + FMT_CONSTEXPR const T& map(const T& val) { + static_assert( + has_formatter::value || + has_fallback_formatter::value, + "Cannot format argument. To enable the use of ostream operator<< " + "include fmt/ostream.h. Otherwise specialize the formatter struct " + "template and implement parse and format methods."); + + return val; + } + template FMT_CONSTEXPR const named_arg_base& map( const named_arg& val) {