mirror of
https://github.com/fmtlib/fmt.git
synced 2025-03-01 01:13:32 +00:00
Replace ArgVisitor::visit with a free visit function
This commit is contained in:
parent
caa60b9c99
commit
c9dc41ab3f
21
fmt/format.h
21
fmt/format.h
@ -1535,6 +1535,13 @@ typedef basic_format_args<basic_format_context<wchar_t>> wformat_args;
|
|||||||
|
|
||||||
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
|
#define FMT_DISPATCH(call) static_cast<Impl*>(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 Visitor>
|
template <typename Visitor>
|
||||||
typename std::result_of<Visitor(int)>::type visit(Visitor &&vis,
|
typename std::result_of<Visitor(int)>::type visit(Visitor &&vis,
|
||||||
format_arg arg) {
|
format_arg arg) {
|
||||||
@ -1738,18 +1745,6 @@ class ArgVisitor {
|
|||||||
Result operator()(format_arg::CustomValue value) {
|
Result operator()(format_arg::CustomValue value) {
|
||||||
return FMT_DISPATCH(visit_custom(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<Impl*>(this), arg);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Alignment {
|
enum Alignment {
|
||||||
@ -3683,7 +3678,7 @@ void do_format_arg(BasicWriter<Char> &writer, const internal::Arg &arg,
|
|||||||
FMT_THROW(format_error("missing '}' in format string"));
|
FMT_THROW(format_error("missing '}' in format string"));
|
||||||
|
|
||||||
// Format argument.
|
// Format argument.
|
||||||
ArgFormatter(writer, ctx, spec).visit(arg);
|
visit(ArgFormatter(writer, ctx, spec), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Formats arguments and writes the output to the writer. */
|
/** Formats arguments and writes the output to the writer. */
|
||||||
|
26
fmt/printf.h
26
fmt/printf.h
@ -388,7 +388,7 @@ unsigned printf_context<Char, AF>::parse_header(
|
|||||||
spec.width_ = internal::parse_nonnegative_int(s);
|
spec.width_ = internal::parse_nonnegative_int(s);
|
||||||
} else if (*s == '*') {
|
} else if (*s == '*') {
|
||||||
++s;
|
++s;
|
||||||
spec.width_ = internal::WidthHandler(spec).visit(get_arg(s));
|
spec.width_ = visit(internal::WidthHandler(spec), get_arg(s));
|
||||||
}
|
}
|
||||||
return arg_index;
|
return arg_index;
|
||||||
}
|
}
|
||||||
@ -420,13 +420,13 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
|
|||||||
spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
|
spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
|
||||||
} else if (*s == '*') {
|
} else if (*s == '*') {
|
||||||
++s;
|
++s;
|
||||||
spec.precision_ = internal::PrecisionHandler().visit(get_arg(s));
|
spec.precision_ = visit(internal::PrecisionHandler(), get_arg(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using internal::Arg;
|
using internal::Arg;
|
||||||
Arg arg = get_arg(s, arg_index);
|
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<int>(HASH_FLAG);
|
spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
|
||||||
if (spec.fill_ == '0') {
|
if (spec.fill_ == '0') {
|
||||||
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
|
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
|
||||||
@ -440,24 +440,24 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
|
|||||||
switch (*s++) {
|
switch (*s++) {
|
||||||
case 'h':
|
case 'h':
|
||||||
if (*s == 'h')
|
if (*s == 'h')
|
||||||
ArgConverter<signed char>(arg, *++s).visit(arg);
|
visit(ArgConverter<signed char>(arg, *++s), arg);
|
||||||
else
|
else
|
||||||
ArgConverter<short>(arg, *s).visit(arg);
|
visit(ArgConverter<short>(arg, *s), arg);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (*s == 'l')
|
if (*s == 'l')
|
||||||
ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
|
visit(ArgConverter<fmt::LongLong>(arg, *++s), arg);
|
||||||
else
|
else
|
||||||
ArgConverter<long>(arg, *s).visit(arg);
|
visit(ArgConverter<long>(arg, *s), arg);
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
ArgConverter<intmax_t>(arg, *s).visit(arg);
|
visit(ArgConverter<intmax_t>(arg, *s), arg);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
ArgConverter<std::size_t>(arg, *s).visit(arg);
|
visit(ArgConverter<std::size_t>(arg, *s), arg);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
|
visit(ArgConverter<std::ptrdiff_t>(arg, *s), arg);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
// printf produces garbage when 'L' is omitted for long double, no
|
// printf produces garbage when 'L' is omitted for long double, no
|
||||||
@ -465,7 +465,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
--s;
|
--s;
|
||||||
ArgConverter<void>(arg, *s).visit(arg);
|
visit(ArgConverter<void>(arg, *s), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse type.
|
// Parse type.
|
||||||
@ -480,7 +480,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
|
|||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
// TODO: handle wchar_t
|
// TODO: handle wchar_t
|
||||||
internal::CharConverter(arg).visit(arg);
|
visit(internal::CharConverter(arg), arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +488,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
|
|||||||
start = s;
|
start = s;
|
||||||
|
|
||||||
// Format argument.
|
// Format argument.
|
||||||
AF(writer, spec).visit(arg);
|
visit(AF(writer, spec), arg);
|
||||||
}
|
}
|
||||||
internal::write(writer, start, s);
|
internal::write(writer, start, s);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ TEST(FormatTest, ArgConverter) {
|
|||||||
Arg arg = Arg();
|
Arg arg = Arg();
|
||||||
arg.type = Arg::LONG_LONG;
|
arg.type = Arg::LONG_LONG;
|
||||||
arg.long_long_value = std::numeric_limits<fmt::LongLong>::max();
|
arg.long_long_value = std::numeric_limits<fmt::LongLong>::max();
|
||||||
fmt::internal::ArgConverter<fmt::LongLong>(arg, 'd').visit(arg);
|
visit(fmt::internal::ArgConverter<fmt::LongLong>(arg, 'd'), arg);
|
||||||
EXPECT_EQ(Arg::LONG_LONG, arg.type);
|
EXPECT_EQ(Arg::LONG_LONG, arg.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ TEST(OStreamTest, CustomArg) {
|
|||||||
fmt::format_context ctx("}", fmt::format_args());
|
fmt::format_context ctx("}", fmt::format_args());
|
||||||
fmt::FormatSpec spec;
|
fmt::FormatSpec spec;
|
||||||
TestArgFormatter af(writer, ctx, spec);
|
TestArgFormatter af(writer, ctx, spec);
|
||||||
af.visit(fmt::internal::MakeArg<fmt::format_context>(TestEnum()));
|
visit(af, fmt::internal::MakeArg<fmt::format_context>(TestEnum()));
|
||||||
EXPECT_EQ("TestEnum", writer.str());
|
EXPECT_EQ("TestEnum", writer.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,7 +628,7 @@ struct TestVisitor : fmt::ArgVisitor<TestVisitor, Result> {
|
|||||||
|
|
||||||
#define EXPECT_RESULT_(Char, type_code, value) { \
|
#define EXPECT_RESULT_(Char, type_code, value) { \
|
||||||
Arg arg = make_arg<Char>(value); \
|
Arg arg = make_arg<Char>(value); \
|
||||||
Result result = TestVisitor().visit(arg); \
|
Result result = fmt::visit(TestVisitor(), arg); \
|
||||||
EXPECT_EQ(Arg::type_code, result.arg.type); \
|
EXPECT_EQ(Arg::type_code, result.arg.type); \
|
||||||
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
|
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
|
||||||
}
|
}
|
||||||
@ -653,7 +653,7 @@ TEST(ArgVisitorTest, VisitAll) {
|
|||||||
const void *p = STR;
|
const void *p = STR;
|
||||||
EXPECT_RESULT(POINTER, p);
|
EXPECT_RESULT(POINTER, p);
|
||||||
::Test t;
|
::Test t;
|
||||||
Result result = TestVisitor().visit(make_arg<char>(t));
|
Result result = visit(TestVisitor(), make_arg<char>(t));
|
||||||
EXPECT_EQ(Arg::CUSTOM, result.arg.type);
|
EXPECT_EQ(Arg::CUSTOM, result.arg.type);
|
||||||
EXPECT_EQ(&t, result.arg.custom.value);
|
EXPECT_EQ(&t, result.arg.custom.value);
|
||||||
}
|
}
|
||||||
@ -668,7 +668,7 @@ struct TestAnyVisitor : fmt::ArgVisitor<TestAnyVisitor, Result> {
|
|||||||
|
|
||||||
#undef EXPECT_RESULT
|
#undef EXPECT_RESULT
|
||||||
#define EXPECT_RESULT(type_code, value) { \
|
#define EXPECT_RESULT(type_code, value) { \
|
||||||
Result result = TestAnyVisitor().visit(make_arg<char>(value)); \
|
Result result = visit(TestAnyVisitor(), make_arg<char>(value)); \
|
||||||
EXPECT_EQ(Arg::type_code, result.arg.type); \
|
EXPECT_EQ(Arg::type_code, result.arg.type); \
|
||||||
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
|
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
|
||||||
}
|
}
|
||||||
@ -688,7 +688,7 @@ struct TestUnhandledVisitor :
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define EXPECT_UNHANDLED(value) \
|
#define EXPECT_UNHANDLED(value) \
|
||||||
EXPECT_STREQ("test", TestUnhandledVisitor().visit(make_arg<wchar_t>(value)));
|
EXPECT_STREQ("test", visit(TestUnhandledVisitor(), make_arg<wchar_t>(value)));
|
||||||
|
|
||||||
TEST(ArgVisitorTest, VisitUnhandledArg) {
|
TEST(ArgVisitorTest, VisitUnhandledArg) {
|
||||||
EXPECT_UNHANDLED(42);
|
EXPECT_UNHANDLED(42);
|
||||||
@ -710,7 +710,7 @@ TEST(ArgVisitorTest, VisitUnhandledArg) {
|
|||||||
TEST(ArgVisitorTest, VisitInvalidArg) {
|
TEST(ArgVisitorTest, VisitInvalidArg) {
|
||||||
Arg arg = Arg();
|
Arg arg = Arg();
|
||||||
arg.type = static_cast<Arg::Type>(Arg::NONE);
|
arg.type = static_cast<Arg::Type>(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.
|
// Tests fmt::internal::count_digits for integer type Int.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user