From cd2c78fb8a295c429926526f34be1b7ff10a8354 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 8 May 2021 20:54:18 -0700 Subject: [PATCH] Use write directly in formatter specializations --- include/fmt/format.h | 60 ++++++++++++++++++++++++++++---------------- include/fmt/printf.h | 3 ++- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 1378226c..d802ee59 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1482,8 +1482,11 @@ OutputIt write_bytes(OutputIt out, string_view bytes, } template -constexpr OutputIt write_char(OutputIt out, Char value, - const basic_format_specs& specs) { +FMT_CONSTEXPR OutputIt write(OutputIt out, Char value, + const basic_format_specs& specs, + locale_ref loc = {}) { + if (specs.type && specs.type != 'c') + return write(out, static_cast(value), specs, loc); return write_padded(out, specs, 1, [=](reserve_iterator it) { *it++ = value; return it; @@ -1598,10 +1601,12 @@ FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { prefix += (1u + (value > 0xff ? 1 : 0)) << 24; } -template -FMT_CONSTEXPR OutputIt write_int(OutputIt out, T value, - const basic_format_specs& specs, - locale_ref loc) { +template ::value && + !std::is_same::value)> +FMT_CONSTEXPR OutputIt write(OutputIt out, T value, + const basic_format_specs& specs, + locale_ref loc) { auto prefix = 0u; auto abs_value = static_cast>(value); if (is_negative(value)) { @@ -1657,7 +1662,7 @@ FMT_CONSTEXPR OutputIt write_int(OutputIt out, T value, }); } case 'c': - return write_char(out, static_cast(abs_value), specs); + return write(out, static_cast(abs_value), specs); default: FMT_THROW(format_error("invalid type specifier")); } @@ -1679,6 +1684,13 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view s, return copy_str(data, data + size, it); }); } +template +FMT_CONSTEXPR OutputIt write(OutputIt out, + basic_string_view> s, + const basic_format_specs& specs, + locale_ref) { + return write(out, s, specs); // Adapt write to formatter::format. +} template OutputIt write_nonfinite(OutputIt out, bool isinf, @@ -2021,9 +2033,14 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, T value) { out, static_cast::type>(value)); } -template -constexpr OutputIt write(OutputIt out, bool value) { - return write(out, string_view(value ? "true" : "false")); +template ::value)> +FMT_CONSTEXPR OutputIt write(OutputIt out, T value, + const basic_format_specs& specs = {}, + locale_ref = {}) { + return specs.type && specs.type != 's' + ? write(out, value ? 1 : 0, specs, {}) + : write(out, string_view(value ? "true" : "false"), specs); } template @@ -2044,9 +2061,11 @@ FMT_CONSTEXPR_CHAR_TRAITS OutputIt write(OutputIt out, const Char* value) { return out; } -template -OutputIt write(OutputIt out, const void* value) { - return write_ptr(out, to_uintptr(value), nullptr); +template ::value)> +OutputIt write(OutputIt out, const T* value, + const basic_format_specs& specs = {}, locale_ref = {}) { + return write_ptr(out, to_uintptr(value), &specs); } template @@ -2152,12 +2171,12 @@ class arg_formatter_base { FMT_CONSTEXPR void on_int() { // char is only formatted as int if there are specs. - formatter.out_ = - detail::write_int(formatter.out_, static_cast(value), - formatter.specs_, formatter.locale_); + formatter.out_ = detail::write(formatter.out_, static_cast(value), + formatter.specs_, formatter.locale_); } FMT_CONSTEXPR void on_char() { - formatter.out_ = write_char(formatter.out_, value, formatter.specs_); + formatter.out_ = + detail::write(formatter.out_, value, formatter.specs_); } }; @@ -2199,7 +2218,7 @@ class arg_formatter_base { template ::value)> FMT_CONSTEXPR FMT_INLINE iterator operator()(T value) { - return out_ = detail::write_int(out_, value, specs_, locale_); + return out_ = detail::write(out_, value, specs_, locale_); } FMT_CONSTEXPR iterator operator()(Char value) { @@ -2883,10 +2902,7 @@ struct formatter( specs.precision, specs.precision_ref, ctx); - using af = detail::arg_formatter; - return visit_format_arg(af(ctx, specs), - detail::make_arg(val)); + return detail::write(ctx.out(), val, specs, ctx.locale()); } private: diff --git a/include/fmt/printf.h b/include/fmt/printf.h index ee6a20c8..c65fe404 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -247,7 +247,8 @@ class printf_arg_formatter : public detail::arg_formatter_base { // ignored for non-numeric types if (fmt_specs.align == align::none || fmt_specs.align == align::numeric) fmt_specs.align = align::right; - return write_char(this->out(), static_cast(value), fmt_specs); + return detail::write(this->out(), static_cast(value), + fmt_specs); } return base::operator()(value); }