From e2a66c58e5813a8528225954f43e11caed159ba7 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 16 Jul 2014 07:55:31 -0700 Subject: [PATCH] Simplify and test ArgVisitor. --- format.h | 18 ++--------- test/util-test.cc | 77 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/format.h b/format.h index fec1099f..d10c2a3c 100644 --- a/format.h +++ b/format.h @@ -734,31 +734,17 @@ class ArgVisitor { Result visit_unhandled_arg() { return Result(); } Result visit_int(int value) { - return FMT_DISPATCH(visit_any_signed(value)); + return FMT_DISPATCH(visit_any_int(value)); } Result visit_long_long(LongLong value) { - return FMT_DISPATCH(visit_any_signed(value)); - } - - // Visit any signed integer. - template - Result visit_any_signed(T value) { return FMT_DISPATCH(visit_any_int(value)); } - Result visit_uint(unsigned value) { - return FMT_DISPATCH(visit_any_unsigned(value)); + return FMT_DISPATCH(visit_any_int(value)); } Result visit_ulong_long(ULongLong value) { - return FMT_DISPATCH(visit_any_unsigned(value)); - } - - // Visit any unsigned integer. - template - Result visit_any_unsigned(T value) { return FMT_DISPATCH(visit_any_int(value)); } - template Result visit_any_int(T) { return FMT_DISPATCH(visit_unhandled_arg()); diff --git a/test/util-test.cc b/test/util-test.cc index 0b7facc0..561d3924 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -43,6 +43,7 @@ using fmt::StringRef; using fmt::internal::Arg; +using fmt::internal::MakeArg; namespace { std::string GetSystemErrorMessage(int error_code) { @@ -59,7 +60,10 @@ std::string GetSystemErrorMessage(int error_code) { } struct Test {}; -std::ostream &operator<<(std::ostream &os, Test) { return os << "test"; } +template +std::basic_ostream &operator<<(std::basic_ostream &os, Test) { + return os << "test"; +} } TEST(UtilTest, Increment) { @@ -103,7 +107,7 @@ ARG_INFO(CUSTOM, Arg::CustomValue, custom); EXPECT_EQ(value, ArgInfo::get(arg)); \ } -TEST(UtilTest, ArgInfo) { +TEST(ArgTest, ArgInfo) { CHECK_ARG_INFO(INT, int_value, 42); CHECK_ARG_INFO(UINT, uint_value, 42); CHECK_ARG_INFO(LONG_LONG, long_long_value, 42); @@ -124,7 +128,7 @@ TEST(UtilTest, ArgInfo) { #define EXPECT_ARG_(Char, type_code, Type, value) { \ Type expected_value = static_cast(value); \ - Arg arg = fmt::internal::MakeArg(expected_value); \ + Arg arg = MakeArg(expected_value); \ EXPECT_EQ(Arg::type_code, arg.type); \ EXPECT_EQ(expected_value, ArgInfo::get(arg)); \ } @@ -135,7 +139,7 @@ TEST(UtilTest, ArgInfo) { #define EXPECT_ARGW(type_code, Type, value) \ EXPECT_ARG_(wchar_t, type_code, Type, value) -TEST(UtilTest, MakeArg) { +TEST(ArgTest, MakeArg) { // Test bool. EXPECT_ARG(INT, bool, true); @@ -227,7 +231,7 @@ TEST(UtilTest, MakeArg) { EXPECT_ARG(POINTER, const void*, &n); ::Test t; - fmt::internal::Arg arg = fmt::internal::MakeArg(t); + fmt::internal::Arg arg = MakeArg(t); EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type); EXPECT_EQ(&t, arg.custom.value); fmt::Writer w; @@ -239,11 +243,11 @@ TEST(UtilTest, MakeArg) { struct Result { fmt::internal::Arg arg; - Result() : arg(fmt::internal::MakeArg(0xdeadbeef)) {} + Result() : arg(MakeArg(0xdeadbeef)) {} template - Result(const T& value) : arg(fmt::internal::MakeArg(value)) {} - Result(const wchar_t *s) : arg(fmt::internal::MakeArg(s)) {} + Result(const T& value) : arg(MakeArg(value)) {} + Result(const wchar_t *s) : arg(MakeArg(s)) {} }; struct TestVisitor : fmt::internal::ArgVisitor { @@ -273,8 +277,7 @@ struct TestVisitor : fmt::internal::ArgVisitor { #define EXPECT_RESULTW(type_code, value) \ EXPECT_RESULT_(wchar_t, type_code, value) -TEST(UtilTest, ArgVisitor) { - using fmt::internal::MakeArg; +TEST(ArgVisitorTest, VisitAll) { EXPECT_RESULT(INT, 42); EXPECT_RESULT(UINT, 42u); EXPECT_RESULT(LONG_LONG, 42ll); @@ -294,6 +297,60 @@ TEST(UtilTest, ArgVisitor) { EXPECT_EQ(&t, result.arg.custom.value); } +struct TestAnyVisitor : fmt::internal::ArgVisitor { + template + Result visit_any_int(T value) { return value; } + + template + Result visit_any_double(T value) { return value; } +}; + +#undef EXPECT_RESULT +#define EXPECT_RESULT(type_code, value) { \ + Result result = TestAnyVisitor().visit(MakeArg(value)); \ + EXPECT_EQ(Arg::type_code, result.arg.type); \ + EXPECT_EQ(value, ArgInfo::get(result.arg)); \ +} + +TEST(ArgVisitorTest, VisitAny) { + EXPECT_RESULT(INT, 42); + EXPECT_RESULT(UINT, 42u); + EXPECT_RESULT(LONG_LONG, 42ll); + EXPECT_RESULT(ULONG_LONG, 42ull); + EXPECT_RESULT(DOUBLE, 4.2); + EXPECT_RESULT(LONG_DOUBLE, 4.2l); +} + +struct TestUnhandledVisitor : + fmt::internal::ArgVisitor { + const char *visit_unhandled_arg() { return "test"; } +}; + +#define EXPECT_UNHANDLED(value) \ + EXPECT_STREQ("test", TestUnhandledVisitor().visit(MakeArg(value))); + +TEST(ArgVisitorTest, VisitUnhandledArg) { + EXPECT_UNHANDLED(42); + EXPECT_UNHANDLED(42u); + EXPECT_UNHANDLED(42ll); + EXPECT_UNHANDLED(42ull); + EXPECT_UNHANDLED(4.2); + EXPECT_UNHANDLED(4.2l); + EXPECT_UNHANDLED('x'); + const char STR[] = "abc"; + EXPECT_UNHANDLED(STR); + const wchar_t WSTR[] = L"abc"; + EXPECT_UNHANDLED(WSTR); + const void *p = STR; + EXPECT_UNHANDLED(p); + EXPECT_UNHANDLED(::Test()); +} + +TEST(ArgVisitorTest, VisitInvalidArg) { + Arg arg = {static_cast(Arg::CUSTOM + 1)}; + EXPECT_DEBUG_DEATH(TestVisitor().visit(arg), "Assertion"); +} + // Tests fmt::internal::CountDigits for integer type Int. template void TestCountDigits(Int) {