From c5c968cb2235a9bf28d9fcc71781166825f4f7ab Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Fri, 21 May 2021 07:24:21 -0700 Subject: [PATCH] Improve binary size --- include/fmt/format.h | 52 ++++++++++++++++++++++++-------------------- include/fmt/os.h | 3 ++- include/fmt/printf.h | 2 +- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index d0293579..06f7ea12 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1284,8 +1284,8 @@ constexpr OutputIt write_padded(OutputIt out, } template -OutputIt write_bytes(OutputIt out, string_view bytes, - const basic_format_specs& specs) { +FMT_CONSTEXPR OutputIt write_bytes(OutputIt out, string_view bytes, + const basic_format_specs& specs) { return write_padded(out, specs, bytes.size(), [bytes](reserve_iterator it) { const char* data = bytes.data(); @@ -1432,19 +1432,32 @@ FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { prefix += (1u + (value > 0xff ? 1 : 0)) << 24; } -template ::value && !std::is_same::value)> -FMT_CONSTEXPR FMT_INLINE OutputIt -write_int(OutputIt out, T value, const basic_format_specs& specs, - locale_ref loc) { +template struct write_int_arg { + UInt abs_value; + unsigned prefix; +}; + +template +FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign) + -> write_int_arg> { auto prefix = 0u; auto abs_value = static_cast>(value); if (is_negative(value)) { prefix = 0x01000000 | '-'; abs_value = 0 - abs_value; } else { - prefix = data::prefixes[specs.sign]; + prefix = data::prefixes[sign]; } + return {abs_value, prefix}; +} + +template +FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, + const basic_format_specs& specs, + locale_ref loc) -> OutputIt { + static_assert(std::is_same>::value, ""); + auto abs_value = arg.abs_value; + auto prefix = arg.prefix; auto utype = static_cast(specs.type); switch (specs.type) { case 0: @@ -1505,7 +1518,7 @@ template & specs, locale_ref loc) { - return write_int(out, value, specs, loc); + return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } // An inlined version of write used in format string compilation. template & specs, locale_ref loc) { - return write_int(out, value, specs, loc); + return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } -template -FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view s, +template +FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view s, const basic_format_specs& specs) { auto data = s.data(); auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) size = code_point_index(s, to_unsigned(specs.precision)); - auto width = specs.width != 0 - ? compute_width(basic_string_view(data, size)) - : 0; + auto width = + specs.width != 0 ? compute_width(basic_string_view(data, size)) : 0; return write_padded(out, specs, size, width, [=](reserve_iterator it) { return copy_str(data, data + size, it); @@ -1818,14 +1830,6 @@ OutputIt write(OutputIt out, monostate, basic_format_specs = {}, return out; } -template ::value)> -OutputIt write(OutputIt out, string_view value) { - auto it = reserve(out, value.size()); - it = copy_str(value.begin(), value.end(), it); - return base_iterator(out, it); -} - template FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view value) { auto it = reserve(out, value.size()); @@ -1881,7 +1885,7 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, T value, locale_ref = {}) { return specs.type && specs.type != 's' ? write(out, value ? 1 : 0, specs, {}) - : write(out, string_view(value ? "true" : "false"), specs); + : write_bytes(out, value ? "true" : "false", specs); } template diff --git a/include/fmt/os.h b/include/fmt/os.h index 1a6385a0..fca43d0a 100644 --- a/include/fmt/os.h +++ b/include/fmt/os.h @@ -128,7 +128,8 @@ template struct formatter { FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); - out = detail::write(out, to_string_view(ec.category().name())); + out = detail::write_bytes(out, ec.category().name(), + basic_format_specs()); out = detail::write(out, Char(':')); out = detail::write(out, ec.value()); return out; diff --git a/include/fmt/printf.h b/include/fmt/printf.h index b3ddfd5f..3ae8249c 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -202,7 +202,7 @@ class printf_arg_formatter : public arg_formatter { OutputIt write_null_pointer(bool is_string = false) { auto s = this->specs; s.type = 0; - return write(this->out, string_view(is_string ? "(null)" : "(nil)"), s); + return write_bytes(this->out, is_string ? "(null)" : "(nil)", s); } public: