Simplify arg_formatter
This commit is contained in:
parent
30e1302e73
commit
60f5d24411
@ -302,9 +302,13 @@ template <typename OutputIt, typename Context, typename Id>
|
||||
void format_arg(
|
||||
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
||||
Context& ctx, Id arg_id) {
|
||||
ctx.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
|
||||
ctx.arg(arg_id)));
|
||||
auto arg = ctx.arg(arg_id);
|
||||
if (arg.type() == type::custom_type) {
|
||||
visit_format_arg(custom_formatter<Context>(parse_ctx, ctx), arg);
|
||||
} else {
|
||||
ctx.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, typename Context::char_type>(ctx), arg));
|
||||
}
|
||||
}
|
||||
|
||||
// vformat_to is defined in a subnamespace to prevent ADL.
|
||||
@ -366,7 +370,7 @@ auto vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
ctx.advance_to(
|
||||
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
||||
ctx, nullptr, &specs),
|
||||
ctx, &specs),
|
||||
arg));
|
||||
break;
|
||||
}
|
||||
|
@ -2450,8 +2450,6 @@ class arg_formatter : public arg_formatter_base<OutputIt, Char> {
|
||||
using context_type = basic_format_context<OutputIt, Char>;
|
||||
|
||||
context_type& ctx_;
|
||||
basic_format_parse_context<char_type>* parse_ctx_;
|
||||
const Char* ptr_;
|
||||
|
||||
public:
|
||||
using iterator = typename base::iterator;
|
||||
@ -2464,21 +2462,15 @@ class arg_formatter : public arg_formatter_base<OutputIt, Char> {
|
||||
*specs* contains format specifier information for standard argument types.
|
||||
\endrst
|
||||
*/
|
||||
constexpr explicit arg_formatter(
|
||||
context_type& ctx,
|
||||
basic_format_parse_context<char_type>* parse_ctx = nullptr,
|
||||
format_specs* specs = nullptr, const Char* ptr = nullptr)
|
||||
: base(ctx.out(), specs, ctx.locale()),
|
||||
ctx_(ctx),
|
||||
parse_ctx_(parse_ctx),
|
||||
ptr_(ptr) {}
|
||||
constexpr explicit arg_formatter(context_type& ctx,
|
||||
format_specs* specs = nullptr)
|
||||
: base(ctx.out(), specs, ctx.locale()), ctx_(ctx) {}
|
||||
|
||||
using base::operator();
|
||||
|
||||
/** Formats an argument of a user-defined type. */
|
||||
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
||||
if (ptr_) advance_to(*parse_ctx_, ptr_);
|
||||
handle.format(*parse_ctx_, ctx_);
|
||||
iterator operator()(typename basic_format_arg<context_type>::handle) {
|
||||
// User-defined types are handled separately because they require access to
|
||||
// the parse context.
|
||||
return ctx_.out();
|
||||
}
|
||||
};
|
||||
@ -3245,8 +3237,8 @@ struct format_handler : detail::error_handler {
|
||||
arg.type());
|
||||
begin = parse_format_specs(begin, end, handler);
|
||||
if (begin == end || *begin != '}') on_error("missing '}' in format string");
|
||||
context.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, Char>(context, &parse_context, &specs), arg));
|
||||
context.advance_to(
|
||||
visit_format_arg(arg_formatter<OutputIt, Char>(context, &specs), arg));
|
||||
return begin;
|
||||
}
|
||||
};
|
||||
@ -3623,7 +3615,7 @@ struct formatter<T, Char,
|
||||
specs.precision, specs.precision_ref, ctx);
|
||||
using af = detail::arg_formatter<typename FormatContext::iterator,
|
||||
typename FormatContext::char_type>;
|
||||
return visit_format_arg(af(ctx, nullptr, &specs),
|
||||
return visit_format_arg(af(ctx, &specs),
|
||||
detail::make_arg<FormatContext>(val));
|
||||
}
|
||||
|
||||
@ -3726,8 +3718,7 @@ template <typename Char = char> class dynamic_formatter {
|
||||
if (specs_.precision >= 0) checker.end_precision();
|
||||
using af = detail::arg_formatter<typename FormatContext::iterator,
|
||||
typename FormatContext::char_type>;
|
||||
visit_format_arg(af(ctx, nullptr, &specs_),
|
||||
detail::make_arg<FormatContext>(val));
|
||||
visit_format_arg(af(ctx, &specs_), detail::make_arg<FormatContext>(val));
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
|
@ -64,26 +64,6 @@ TEST(OStreamTest, Enum) {
|
||||
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
|
||||
}
|
||||
|
||||
struct test_arg_formatter
|
||||
: fmt::detail::arg_formatter<fmt::format_context::iterator, char> {
|
||||
fmt::format_parse_context parse_ctx;
|
||||
test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s)
|
||||
: fmt::detail::arg_formatter<fmt::format_context::iterator, char>(
|
||||
ctx, &parse_ctx, &s),
|
||||
parse_ctx("") {}
|
||||
};
|
||||
|
||||
TEST(OStreamTest, CustomArg) {
|
||||
fmt::memory_buffer buffer;
|
||||
fmt::format_context ctx(fmt::detail::buffer_appender<char>{buffer},
|
||||
fmt::format_args());
|
||||
fmt::format_specs spec;
|
||||
test_arg_formatter af(ctx, spec);
|
||||
fmt::visit_format_arg(
|
||||
af, fmt::detail::make_arg<fmt::format_context>(streamable_enum()));
|
||||
EXPECT_EQ("streamable_enum", std::string(buffer.data(), buffer.size()));
|
||||
}
|
||||
|
||||
TEST(OStreamTest, Format) {
|
||||
EXPECT_EQ("a string", format("{0}", TestString("a string")));
|
||||
std::string s = format("The date is {0}", Date(2012, 12, 9));
|
||||
|
Loading…
Reference in New Issue
Block a user