mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 11:17:35 +02:00
Simplify arg_formatter
This commit is contained in:
@@ -164,8 +164,10 @@ template <typename Range, typename Context, typename Id>
|
|||||||
void format_arg(
|
void format_arg(
|
||||||
basic_format_parse_context<typename Range::value_type>& parse_ctx,
|
basic_format_parse_context<typename Range::value_type>& parse_ctx,
|
||||||
Context& ctx, Id arg_id) {
|
Context& ctx, Id arg_id) {
|
||||||
ctx.advance_to(
|
ctx.advance_to(visit_format_arg(
|
||||||
visit_format_arg(arg_formatter<Range>(ctx, &parse_ctx), ctx.arg(arg_id)));
|
arg_formatter<typename Range::iterator, typename Range::value_type>(
|
||||||
|
ctx, &parse_ctx),
|
||||||
|
ctx.arg(arg_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// vformat_to is defined in a subnamespace to prevent ADL.
|
// vformat_to is defined in a subnamespace to prevent ADL.
|
||||||
@@ -225,8 +227,10 @@ auto vformat_to(Range out, CompiledFormat& cf, basic_format_args<Context> args)
|
|||||||
if (specs.precision >= 0) checker.check_precision();
|
if (specs.precision >= 0) checker.check_precision();
|
||||||
|
|
||||||
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(
|
||||||
visit_format_arg(arg_formatter<Range>(ctx, nullptr, &specs), arg));
|
arg_formatter<typename Range::iterator, typename Range::value_type>(
|
||||||
|
ctx, nullptr, &specs),
|
||||||
|
arg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2723,21 +2723,17 @@ FMT_API void report_error(format_func func, int error_code,
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/** The default argument formatter. */
|
/** The default argument formatter. */
|
||||||
template <typename Range>
|
template <typename OutputIt, typename Char>
|
||||||
class arg_formatter
|
class arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
|
||||||
: public detail::arg_formatter_base<typename Range::iterator,
|
|
||||||
typename Range::value_type> {
|
|
||||||
private:
|
private:
|
||||||
using char_type = typename Range::value_type;
|
using char_type = Char;
|
||||||
using base = detail::arg_formatter_base<typename Range::iterator,
|
using base = detail::arg_formatter_base<OutputIt, Char>;
|
||||||
typename Range::value_type>;
|
using context_type = basic_format_context<OutputIt, Char>;
|
||||||
using context_type = basic_format_context<typename base::iterator, char_type>;
|
|
||||||
|
|
||||||
context_type& ctx_;
|
context_type& ctx_;
|
||||||
basic_format_parse_context<char_type>* parse_ctx_;
|
basic_format_parse_context<char_type>* parse_ctx_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using range = Range;
|
|
||||||
using iterator = typename base::iterator;
|
using iterator = typename base::iterator;
|
||||||
using format_specs = typename base::format_specs;
|
using format_specs = typename base::format_specs;
|
||||||
|
|
||||||
@@ -2990,9 +2986,9 @@ struct formatter<T, Char,
|
|||||||
specs_.width_ref, ctx);
|
specs_.width_ref, ctx);
|
||||||
detail::handle_dynamic_spec<detail::precision_checker>(
|
detail::handle_dynamic_spec<detail::precision_checker>(
|
||||||
specs_.precision, specs_.precision_ref, ctx);
|
specs_.precision, specs_.precision_ref, ctx);
|
||||||
using range_type = detail::output_range<typename FormatContext::iterator,
|
using af = arg_formatter<typename FormatContext::iterator,
|
||||||
typename FormatContext::char_type>;
|
typename FormatContext::char_type>;
|
||||||
return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_),
|
return visit_format_arg(af(ctx, nullptr, &specs_),
|
||||||
detail::make_arg<FormatContext>(val));
|
detail::make_arg<FormatContext>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3086,9 +3082,9 @@ template <typename Char = char> class dynamic_formatter {
|
|||||||
}
|
}
|
||||||
if (specs_.alt) checker.on_hash();
|
if (specs_.alt) checker.on_hash();
|
||||||
if (specs_.precision >= 0) checker.end_precision();
|
if (specs_.precision >= 0) checker.end_precision();
|
||||||
using range = detail::output_range<typename FormatContext::iterator,
|
using af = arg_formatter<typename FormatContext::iterator,
|
||||||
typename FormatContext::char_type>;
|
typename FormatContext::char_type>;
|
||||||
visit_format_arg(arg_formatter<range>(ctx, nullptr, &specs_),
|
visit_format_arg(af(ctx, nullptr, &specs_),
|
||||||
detail::make_arg<FormatContext>(val));
|
detail::make_arg<FormatContext>(val));
|
||||||
return ctx.out();
|
return ctx.out();
|
||||||
}
|
}
|
||||||
@@ -3113,11 +3109,11 @@ FMT_CONSTEXPR void advance_to(
|
|||||||
|
|
||||||
template <typename ArgFormatter, typename Char, typename Context>
|
template <typename ArgFormatter, typename Char, typename Context>
|
||||||
struct format_handler : detail::error_handler {
|
struct format_handler : detail::error_handler {
|
||||||
using range = typename ArgFormatter::range;
|
using iterator = typename ArgFormatter::iterator;
|
||||||
|
|
||||||
format_handler(range r, basic_string_view<Char> str,
|
format_handler(iterator out, basic_string_view<Char> str,
|
||||||
basic_format_args<Context> format_args, detail::locale_ref loc)
|
basic_format_args<Context> format_args, detail::locale_ref loc)
|
||||||
: parse_context(str), context(r.begin(), format_args, loc) {}
|
: parse_context(str), context(out, format_args, loc) {}
|
||||||
|
|
||||||
void on_text(const Char* begin, const Char* end) {
|
void on_text(const Char* begin, const Char* end) {
|
||||||
auto size = detail::to_unsigned(end - begin);
|
auto size = detail::to_unsigned(end - begin);
|
||||||
@@ -3170,7 +3166,7 @@ struct format_handler : detail::error_handler {
|
|||||||
/** Formats arguments and writes the output to the range. */
|
/** Formats arguments and writes the output to the range. */
|
||||||
template <typename ArgFormatter, typename Char, typename Context>
|
template <typename ArgFormatter, typename Char, typename Context>
|
||||||
typename Context::iterator vformat_to(
|
typename Context::iterator vformat_to(
|
||||||
typename ArgFormatter::range out, basic_string_view<Char> format_str,
|
typename ArgFormatter::iterator out, basic_string_view<Char> format_str,
|
||||||
basic_format_args<Context> args,
|
basic_format_args<Context> args,
|
||||||
detail::locale_ref loc = detail::locale_ref()) {
|
detail::locale_ref loc = detail::locale_ref()) {
|
||||||
format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
|
format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
|
||||||
@@ -3334,9 +3330,9 @@ template <typename Char>
|
|||||||
typename buffer_context<Char>::iterator detail::vformat_to(
|
typename buffer_context<Char>::iterator detail::vformat_to(
|
||||||
detail::buffer<Char>& buf, basic_string_view<Char> format_str,
|
detail::buffer<Char>& buf, basic_string_view<Char> format_str,
|
||||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||||
using range = buffer_range<Char>;
|
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||||
return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str),
|
return vformat_to<af>(std::back_inserter(buf), to_string_view(format_str),
|
||||||
args);
|
args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
@@ -3397,9 +3393,8 @@ template <
|
|||||||
inline OutputIt vformat_to(
|
inline OutputIt vformat_to(
|
||||||
OutputIt out, const S& format_str,
|
OutputIt out, const S& format_str,
|
||||||
format_args_t<type_identity_t<OutputIt>, char_t<S>> args) {
|
format_args_t<type_identity_t<OutputIt>, char_t<S>> args) {
|
||||||
using range = detail::output_range<OutputIt, char_t<S>>;
|
using af = arg_formatter<OutputIt, char_t<S>>;
|
||||||
return vformat_to<arg_formatter<range>>(range(out),
|
return vformat_to<af>(out, to_string_view(format_str), args);
|
||||||
to_string_view(format_str), args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,9 +20,9 @@ typename buffer_context<Char>::iterator vformat_to(
|
|||||||
const std::locale& loc, buffer<Char>& buf,
|
const std::locale& loc, buffer<Char>& buf,
|
||||||
basic_string_view<Char> format_str,
|
basic_string_view<Char> format_str,
|
||||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||||
using range = buffer_range<Char>;
|
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||||
return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str), args,
|
return vformat_to<af>(std::back_inserter(buf), to_string_view(format_str),
|
||||||
detail::locale_ref(loc));
|
args, detail::locale_ref(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@@ -56,9 +56,9 @@ template <typename S, typename OutputIt, typename... Args,
|
|||||||
inline OutputIt vformat_to(
|
inline OutputIt vformat_to(
|
||||||
OutputIt out, const std::locale& loc, const S& format_str,
|
OutputIt out, const std::locale& loc, const S& format_str,
|
||||||
format_args_t<type_identity_t<OutputIt>, Char> args) {
|
format_args_t<type_identity_t<OutputIt>, Char> args) {
|
||||||
using range = detail::output_range<OutputIt, Char>;
|
using af = arg_formatter<OutputIt, Char>;
|
||||||
return vformat_to<arg_formatter<range>>(
|
return vformat_to<af>(out, to_string_view(format_str), args,
|
||||||
range(out), to_string_view(format_str), args, detail::locale_ref(loc));
|
detail::locale_ref(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename S, typename... Args,
|
template <typename OutputIt, typename S, typename... Args,
|
||||||
|
@@ -18,10 +18,9 @@
|
|||||||
// A custom argument formatter that doesn't print `-` for floating-point values
|
// A custom argument formatter that doesn't print `-` for floating-point values
|
||||||
// rounded to 0.
|
// rounded to 0.
|
||||||
class custom_arg_formatter
|
class custom_arg_formatter
|
||||||
: public fmt::arg_formatter<fmt::buffer_range<char>> {
|
: public fmt::arg_formatter<fmt::format_context::iterator, char> {
|
||||||
public:
|
public:
|
||||||
using range = fmt::buffer_range<char>;
|
using base = fmt::arg_formatter<fmt::format_context::iterator, char>;
|
||||||
typedef fmt::arg_formatter<range> base;
|
|
||||||
|
|
||||||
custom_arg_formatter(fmt::format_context& ctx,
|
custom_arg_formatter(fmt::format_context& ctx,
|
||||||
fmt::format_parse_context* parse_ctx,
|
fmt::format_parse_context* parse_ctx,
|
||||||
@@ -39,8 +38,10 @@ class custom_arg_formatter
|
|||||||
|
|
||||||
std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) {
|
std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) {
|
||||||
fmt::memory_buffer buffer;
|
fmt::memory_buffer buffer;
|
||||||
|
fmt::internal::buffer<char>& base = buffer;
|
||||||
// Pass custom argument formatter as a template arg to vwrite.
|
// Pass custom argument formatter as a template arg to vwrite.
|
||||||
fmt::vformat_to<custom_arg_formatter>(buffer, format_str, args);
|
fmt::vformat_to<custom_arg_formatter>(std::back_inserter(base), format_str,
|
||||||
|
args);
|
||||||
return std::string(buffer.data(), buffer.size());
|
return std::string(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1847,7 +1847,9 @@ class mock_arg_formatter
|
|||||||
|
|
||||||
static void custom_vformat(fmt::string_view format_str, fmt::format_args args) {
|
static void custom_vformat(fmt::string_view format_str, fmt::format_args args) {
|
||||||
fmt::memory_buffer buffer;
|
fmt::memory_buffer buffer;
|
||||||
fmt::vformat_to<mock_arg_formatter>(buffer, format_str, args);
|
fmt::internal::buffer<char>& base = buffer;
|
||||||
|
fmt::vformat_to<mock_arg_formatter>(std::back_inserter(base), format_str,
|
||||||
|
args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@@ -64,12 +64,13 @@ TEST(OStreamTest, Enum) {
|
|||||||
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
|
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
|
||||||
}
|
}
|
||||||
|
|
||||||
using range = fmt::buffer_range<char>;
|
struct test_arg_formatter
|
||||||
|
: fmt::arg_formatter<fmt::buffer_range<char>::iterator, char> {
|
||||||
struct test_arg_formatter : fmt::arg_formatter<range> {
|
|
||||||
fmt::format_parse_context parse_ctx;
|
fmt::format_parse_context parse_ctx;
|
||||||
test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s)
|
test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s)
|
||||||
: fmt::arg_formatter<range>(ctx, &parse_ctx, &s), parse_ctx("") {}
|
: fmt::arg_formatter<fmt::buffer_range<char>::iterator, char>(
|
||||||
|
ctx, &parse_ctx, &s),
|
||||||
|
parse_ctx("") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(OStreamTest, CustomArg) {
|
TEST(OStreamTest, CustomArg) {
|
||||||
|
Reference in New Issue
Block a user