mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-12 15:39:09 +00:00
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(
|
void format_arg(
|
||||||
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
||||||
Context& ctx, Id arg_id) {
|
Context& ctx, Id arg_id) {
|
||||||
ctx.advance_to(visit_format_arg(
|
auto arg = ctx.arg(arg_id);
|
||||||
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
|
if (arg.type() == type::custom_type) {
|
||||||
ctx.arg(arg_id)));
|
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.
|
// 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);
|
advance_to(parse_ctx, part.arg_id_end);
|
||||||
ctx.advance_to(
|
ctx.advance_to(
|
||||||
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
||||||
ctx, nullptr, &specs),
|
ctx, &specs),
|
||||||
arg));
|
arg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2450,8 +2450,6 @@ class arg_formatter : public arg_formatter_base<OutputIt, Char> {
|
|||||||
using context_type = basic_format_context<OutputIt, Char>;
|
using context_type = basic_format_context<OutputIt, Char>;
|
||||||
|
|
||||||
context_type& ctx_;
|
context_type& ctx_;
|
||||||
basic_format_parse_context<char_type>* parse_ctx_;
|
|
||||||
const Char* ptr_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator = typename base::iterator;
|
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.
|
*specs* contains format specifier information for standard argument types.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
constexpr explicit arg_formatter(
|
constexpr explicit arg_formatter(context_type& ctx,
|
||||||
context_type& ctx,
|
format_specs* specs = nullptr)
|
||||||
basic_format_parse_context<char_type>* parse_ctx = nullptr,
|
: base(ctx.out(), specs, ctx.locale()), ctx_(ctx) {}
|
||||||
format_specs* specs = nullptr, const Char* ptr = nullptr)
|
|
||||||
: base(ctx.out(), specs, ctx.locale()),
|
|
||||||
ctx_(ctx),
|
|
||||||
parse_ctx_(parse_ctx),
|
|
||||||
ptr_(ptr) {}
|
|
||||||
|
|
||||||
using base::operator();
|
using base::operator();
|
||||||
|
|
||||||
/** Formats an argument of a user-defined type. */
|
iterator operator()(typename basic_format_arg<context_type>::handle) {
|
||||||
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
// User-defined types are handled separately because they require access to
|
||||||
if (ptr_) advance_to(*parse_ctx_, ptr_);
|
// the parse context.
|
||||||
handle.format(*parse_ctx_, ctx_);
|
|
||||||
return ctx_.out();
|
return ctx_.out();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3245,8 +3237,8 @@ struct format_handler : detail::error_handler {
|
|||||||
arg.type());
|
arg.type());
|
||||||
begin = parse_format_specs(begin, end, handler);
|
begin = parse_format_specs(begin, end, handler);
|
||||||
if (begin == end || *begin != '}') on_error("missing '}' in format string");
|
if (begin == end || *begin != '}') on_error("missing '}' in format string");
|
||||||
context.advance_to(visit_format_arg(
|
context.advance_to(
|
||||||
arg_formatter<OutputIt, Char>(context, &parse_context, &specs), arg));
|
visit_format_arg(arg_formatter<OutputIt, Char>(context, &specs), arg));
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3623,7 +3615,7 @@ struct formatter<T, Char,
|
|||||||
specs.precision, specs.precision_ref, ctx);
|
specs.precision, specs.precision_ref, ctx);
|
||||||
using af = detail::arg_formatter<typename FormatContext::iterator,
|
using af = detail::arg_formatter<typename FormatContext::iterator,
|
||||||
typename FormatContext::char_type>;
|
typename FormatContext::char_type>;
|
||||||
return visit_format_arg(af(ctx, nullptr, &specs),
|
return visit_format_arg(af(ctx, &specs),
|
||||||
detail::make_arg<FormatContext>(val));
|
detail::make_arg<FormatContext>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3726,8 +3718,7 @@ template <typename Char = char> class dynamic_formatter {
|
|||||||
if (specs_.precision >= 0) checker.end_precision();
|
if (specs_.precision >= 0) checker.end_precision();
|
||||||
using af = detail::arg_formatter<typename FormatContext::iterator,
|
using af = detail::arg_formatter<typename FormatContext::iterator,
|
||||||
typename FormatContext::char_type>;
|
typename FormatContext::char_type>;
|
||||||
visit_format_arg(af(ctx, nullptr, &specs_),
|
visit_format_arg(af(ctx, &specs_), detail::make_arg<FormatContext>(val));
|
||||||
detail::make_arg<FormatContext>(val));
|
|
||||||
return ctx.out();
|
return ctx.out();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,26 +64,6 @@ TEST(OStreamTest, Enum) {
|
|||||||
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_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) {
|
TEST(OStreamTest, Format) {
|
||||||
EXPECT_EQ("a string", format("{0}", TestString("a string")));
|
EXPECT_EQ("a string", format("{0}", TestString("a string")));
|
||||||
std::string s = format("The date is {0}", Date(2012, 12, 9));
|
std::string s = format("The date is {0}", Date(2012, 12, 9));
|
||||||
|
Loading…
Reference in New Issue
Block a user