From f19d8f9655d550234f19c6c1f5a99c7eda798c0e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 14 Aug 2016 07:28:20 -0700 Subject: [PATCH] Improve error reporting (#357) --- fmt/format.h | 45 ++++++++++++++++++++++++++++++++++++++------- fmt/ostream.h | 4 ++-- fmt/posix.h | 19 ------------------- fmt/time.h | 4 ++-- test/format-test.cc | 4 ++-- test/util-test.cc | 4 ++-- 6 files changed, 46 insertions(+), 34 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index 44bbf047..46e93c99 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1115,13 +1115,16 @@ template struct Conditional { typedef F type; }; // For bcc32 which doesn't understand ! in template arguments. -template +template struct Not { enum { value = 0 }; }; -template<> +template <> struct Not { enum { value = 1 }; }; -template struct LConvCheck { +template +struct False { enum { value = 0 }; }; + +template struct LConvCheck { LConvCheck(int) {} }; @@ -1136,6 +1139,35 @@ inline StringRef thousands_sep( inline fmt::StringRef thousands_sep(...) { return ""; } +#define FMT_CONCAT(a, b) a##b + +#if FMT_GCC_VERSION >= 407 +# define FMT_UNUSED __attribute__((unused)) +#else +# define FMT_UNUSED +#endif + +#ifndef FMT_USE_STATIC_ASSERT +# define FMT_USE_STATIC_ASSERT 0 +#endif + +#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ + (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 +# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) +#else +# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) +# define FMT_STATIC_ASSERT(cond, message) \ + typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED +#endif + +template +void format_arg(Formatter &, const Char *, const T &) { + FMT_STATIC_ASSERT(False::value, + "Cannot format argument. To enable the use of ostream " + "operator<< include fmt/ostream.h. Otherwise provide " + "an overload of format_arg."); +} + // Makes an Arg object from any type. template class MakeValue : public Arg { @@ -1179,9 +1211,9 @@ class MakeValue : public Arg { template static void format_custom_arg( void *formatter, const void *arg, void *format_str_ptr) { - format(*static_cast(formatter), - *static_cast(format_str_ptr), - *static_cast(arg)); + format_arg(*static_cast(formatter), + *static_cast(format_str_ptr), + *static_cast(arg)); } public: @@ -3323,7 +3355,6 @@ void arg(WStringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 -#define FMT_CONCAT(a, b) a##b #define FMT_FOR_EACH_(N, f, ...) \ FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) #define FMT_FOR_EACH(f, ...) \ diff --git a/fmt/ostream.h b/fmt/ostream.h index 00b7d717..e21b2f6d 100644 --- a/fmt/ostream.h +++ b/fmt/ostream.h @@ -73,8 +73,8 @@ void write(std::ostream &os, Writer &w); // Formats a value. template -void format(BasicFormatter &f, - const Char *&format_str, const T &value) { +void format_arg(BasicFormatter &f, + const Char *&format_str, const T &value) { internal::MemoryBuffer buffer; internal::FormatBuf format_buf(buffer); diff --git a/fmt/posix.h b/fmt/posix.h index 229a98b7..7c2b0b5e 100644 --- a/fmt/posix.h +++ b/fmt/posix.h @@ -51,25 +51,6 @@ # endif #endif -#if FMT_GCC_VERSION >= 407 -# define FMT_UNUSED __attribute__((unused)) -#else -# define FMT_UNUSED -#endif - -#ifndef FMT_USE_STATIC_ASSERT -# define FMT_USE_STATIC_ASSERT 0 -#endif - -#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 -# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) -#else -# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) -# define FMT_STATIC_ASSERT(cond, message) \ - typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED -#endif - // Retries the expression while it evaluates to error_result and errno // equals to EINTR. #ifndef _WIN32 diff --git a/fmt/time.h b/fmt/time.h index 5375fc81..ccdad77f 100644 --- a/fmt/time.h +++ b/fmt/time.h @@ -15,8 +15,8 @@ namespace fmt { template -void format(BasicFormatter &f, - const char *&format_str, const std::tm &tm) { +void format_arg(BasicFormatter &f, + const char *&format_str, const std::tm &tm) { if (*format_str == ':') ++format_str; const char *end = format_str; diff --git a/test/format-test.cc b/test/format-test.cc index 6eb7e2a7..37d69350 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1366,7 +1366,7 @@ TEST(FormatterTest, FormatCStringRef) { EXPECT_EQ("test", format("{0}", CStringRef("test"))); } -void format(fmt::BasicFormatter &f, const char *, const Date &d) { +void format_arg(fmt::BasicFormatter &f, const char *, const Date &d) { f.writer() << d.year() << '-' << d.month() << '-' << d.day(); } @@ -1379,7 +1379,7 @@ TEST(FormatterTest, FormatCustom) { class Answer {}; template -void format(fmt::BasicFormatter &f, const Char *, Answer) { +void format_arg(fmt::BasicFormatter &f, const Char *, Answer) { f.writer() << "42"; } diff --git a/test/util-test.cc b/test/util-test.cc index 1bb7e5d1..d67dd52c 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -64,7 +64,7 @@ namespace { struct Test {}; template -void format(fmt::BasicFormatter &f, const Char *, Test) { +void format_arg(fmt::BasicFormatter &f, const Char *, Test) { f.writer() << "test"; } @@ -581,7 +581,7 @@ struct CustomFormatter { typedef char Char; }; -void format(CustomFormatter &, const char *&s, const Test &) { +void format_arg(CustomFormatter &, const char *&s, const Test &) { s = "custom_format"; }