diff --git a/fmt/format.h b/fmt/format.h index d0a01468..e6f01725 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1535,6 +1535,13 @@ typedef basic_format_args> wformat_args; #define FMT_DISPATCH(call) static_cast(this)->call +/** + \rst + Visits an argument dispatching to the appropriate visit method based on + the argument type. For example, if the argument type is ``double`` then + ``vis(value)`` will be called with the value of type ``double``. + \endrst + */ template typename std::result_of::type visit(Visitor &&vis, format_arg arg) { @@ -1738,18 +1745,6 @@ class ArgVisitor { Result operator()(format_arg::CustomValue value) { return FMT_DISPATCH(visit_custom(value)); } - - /** - \rst - Visits an argument dispatching to the appropriate visit method based on - the argument type. For example, if the argument type is ``double`` then - the `~fmt::ArgVisitor::operator()(double)` method of the *Impl* class will - be called. - \endrst - */ - Result visit(const format_arg &arg) { - return fmt::visit(*static_cast(this), arg); - } }; enum Alignment { @@ -3683,7 +3678,7 @@ void do_format_arg(BasicWriter &writer, const internal::Arg &arg, FMT_THROW(format_error("missing '}' in format string")); // Format argument. - ArgFormatter(writer, ctx, spec).visit(arg); + visit(ArgFormatter(writer, ctx, spec), arg); } /** Formats arguments and writes the output to the writer. */ diff --git a/fmt/printf.h b/fmt/printf.h index 8f9278fe..c8d7b3dc 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -388,7 +388,7 @@ unsigned printf_context::parse_header( spec.width_ = internal::parse_nonnegative_int(s); } else if (*s == '*') { ++s; - spec.width_ = internal::WidthHandler(spec).visit(get_arg(s)); + spec.width_ = visit(internal::WidthHandler(spec), get_arg(s)); } return arg_index; } @@ -420,13 +420,13 @@ void printf_context::format(BasicWriter &writer) { spec.precision_ = static_cast(internal::parse_nonnegative_int(s)); } else if (*s == '*') { ++s; - spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); + spec.precision_ = visit(internal::PrecisionHandler(), get_arg(s)); } } using internal::Arg; Arg arg = get_arg(s, arg_index); - if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg)) + if (spec.flag(HASH_FLAG) && visit(internal::IsZeroInt(), arg)) spec.flags_ &= ~internal::to_unsigned(HASH_FLAG); if (spec.fill_ == '0') { if (arg.type <= Arg::LAST_NUMERIC_TYPE) @@ -440,24 +440,24 @@ void printf_context::format(BasicWriter &writer) { switch (*s++) { case 'h': if (*s == 'h') - ArgConverter(arg, *++s).visit(arg); + visit(ArgConverter(arg, *++s), arg); else - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); break; case 'l': if (*s == 'l') - ArgConverter(arg, *++s).visit(arg); + visit(ArgConverter(arg, *++s), arg); else - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); break; case 'j': - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); break; case 'z': - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); break; case 't': - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); break; case 'L': // printf produces garbage when 'L' is omitted for long double, no @@ -465,7 +465,7 @@ void printf_context::format(BasicWriter &writer) { break; default: --s; - ArgConverter(arg, *s).visit(arg); + visit(ArgConverter(arg, *s), arg); } // Parse type. @@ -480,7 +480,7 @@ void printf_context::format(BasicWriter &writer) { break; case 'c': // TODO: handle wchar_t - internal::CharConverter(arg).visit(arg); + visit(internal::CharConverter(arg), arg); break; } } @@ -488,7 +488,7 @@ void printf_context::format(BasicWriter &writer) { start = s; // Format argument. - AF(writer, spec).visit(arg); + visit(AF(writer, spec), arg); } internal::write(writer, start, s); } diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index e29a6fe6..4ad2bccf 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -46,7 +46,7 @@ TEST(FormatTest, ArgConverter) { Arg arg = Arg(); arg.type = Arg::LONG_LONG; arg.long_long_value = std::numeric_limits::max(); - fmt::internal::ArgConverter(arg, 'd').visit(arg); + visit(fmt::internal::ArgConverter(arg, 'd'), arg); EXPECT_EQ(Arg::LONG_LONG, arg.type); } diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 2d1ace63..d600714c 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -69,7 +69,7 @@ TEST(OStreamTest, CustomArg) { fmt::format_context ctx("}", fmt::format_args()); fmt::FormatSpec spec; TestArgFormatter af(writer, ctx, spec); - af.visit(fmt::internal::MakeArg(TestEnum())); + visit(af, fmt::internal::MakeArg(TestEnum())); EXPECT_EQ("TestEnum", writer.str()); } diff --git a/test/util-test.cc b/test/util-test.cc index b553427c..7bca57e4 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -628,7 +628,7 @@ struct TestVisitor : fmt::ArgVisitor { #define EXPECT_RESULT_(Char, type_code, value) { \ Arg arg = make_arg(value); \ - Result result = TestVisitor().visit(arg); \ + Result result = fmt::visit(TestVisitor(), arg); \ EXPECT_EQ(Arg::type_code, result.arg.type); \ EXPECT_EQ(value, ArgInfo::get(result.arg)); \ } @@ -653,7 +653,7 @@ TEST(ArgVisitorTest, VisitAll) { const void *p = STR; EXPECT_RESULT(POINTER, p); ::Test t; - Result result = TestVisitor().visit(make_arg(t)); + Result result = visit(TestVisitor(), make_arg(t)); EXPECT_EQ(Arg::CUSTOM, result.arg.type); EXPECT_EQ(&t, result.arg.custom.value); } @@ -668,7 +668,7 @@ struct TestAnyVisitor : fmt::ArgVisitor { #undef EXPECT_RESULT #define EXPECT_RESULT(type_code, value) { \ - Result result = TestAnyVisitor().visit(make_arg(value)); \ + Result result = visit(TestAnyVisitor(), make_arg(value)); \ EXPECT_EQ(Arg::type_code, result.arg.type); \ EXPECT_EQ(value, ArgInfo::get(result.arg)); \ } @@ -688,7 +688,7 @@ struct TestUnhandledVisitor : }; #define EXPECT_UNHANDLED(value) \ - EXPECT_STREQ("test", TestUnhandledVisitor().visit(make_arg(value))); + EXPECT_STREQ("test", visit(TestUnhandledVisitor(), make_arg(value))); TEST(ArgVisitorTest, VisitUnhandledArg) { EXPECT_UNHANDLED(42); @@ -710,7 +710,7 @@ TEST(ArgVisitorTest, VisitUnhandledArg) { TEST(ArgVisitorTest, VisitInvalidArg) { Arg arg = Arg(); arg.type = static_cast(Arg::NONE); - EXPECT_ASSERT(TestVisitor().visit(arg), "invalid argument type"); + EXPECT_ASSERT(visit(TestVisitor(), arg), "invalid argument type"); } // Tests fmt::internal::count_digits for integer type Int.