Improve binary size

This commit is contained in:
Victor Zverovich 2021-05-21 07:24:21 -07:00
parent 128cbdeb2f
commit c5c968cb22
3 changed files with 31 additions and 26 deletions

View File

@ -1284,8 +1284,8 @@ constexpr OutputIt write_padded(OutputIt out,
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
OutputIt write_bytes(OutputIt out, string_view bytes, FMT_CONSTEXPR OutputIt write_bytes(OutputIt out, string_view bytes,
const basic_format_specs<Char>& specs) { const basic_format_specs<Char>& specs) {
return write_padded(out, specs, bytes.size(), return write_padded(out, specs, bytes.size(),
[bytes](reserve_iterator<OutputIt> it) { [bytes](reserve_iterator<OutputIt> it) {
const char* data = bytes.data(); 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; prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
} }
template <typename Char, typename OutputIt, typename T, template <typename UInt> struct write_int_arg {
FMT_ENABLE_IF(is_integral<T>::value && !std::is_same<T, bool>::value)> UInt abs_value;
FMT_CONSTEXPR FMT_INLINE OutputIt unsigned prefix;
write_int(OutputIt out, T value, const basic_format_specs<Char>& specs, };
locale_ref loc) {
template <typename T>
FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign)
-> write_int_arg<uint32_or_64_or_128_t<T>> {
auto prefix = 0u; auto prefix = 0u;
auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value); auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
if (is_negative(value)) { if (is_negative(value)) {
prefix = 0x01000000 | '-'; prefix = 0x01000000 | '-';
abs_value = 0 - abs_value; abs_value = 0 - abs_value;
} else { } else {
prefix = data::prefixes[specs.sign]; prefix = data::prefixes[sign];
} }
return {abs_value, prefix};
}
template <typename Char, typename OutputIt, typename T>
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
const basic_format_specs<Char>& specs,
locale_ref loc) -> OutputIt {
static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
auto abs_value = arg.abs_value;
auto prefix = arg.prefix;
auto utype = static_cast<unsigned>(specs.type); auto utype = static_cast<unsigned>(specs.type);
switch (specs.type) { switch (specs.type) {
case 0: case 0:
@ -1505,7 +1518,7 @@ template <typename Char, typename OutputIt, typename T,
FMT_CONSTEXPR OutputIt write(OutputIt out, T value, FMT_CONSTEXPR OutputIt write(OutputIt out, T value,
const basic_format_specs<Char>& specs, const basic_format_specs<Char>& specs,
locale_ref loc) { 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. // An inlined version of write used in format string compilation.
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
@ -1515,19 +1528,18 @@ template <typename Char, typename OutputIt, typename T,
FMT_CONSTEXPR FMT_INLINE OutputIt write(OutputIt out, T value, FMT_CONSTEXPR FMT_INLINE OutputIt write(OutputIt out, T value,
const basic_format_specs<Char>& specs, const basic_format_specs<Char>& specs,
locale_ref loc) { locale_ref loc) {
return write_int(out, value, specs, loc); return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
} }
template <typename OutputIt, typename StrChar, typename Char> template <typename Char, typename OutputIt>
FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view<StrChar> s, FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view<Char> s,
const basic_format_specs<Char>& specs) { const basic_format_specs<Char>& specs) {
auto data = s.data(); auto data = s.data();
auto size = s.size(); auto size = s.size();
if (specs.precision >= 0 && to_unsigned(specs.precision) < size) if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
size = code_point_index(s, to_unsigned(specs.precision)); size = code_point_index(s, to_unsigned(specs.precision));
auto width = specs.width != 0 auto width =
? compute_width(basic_string_view<StrChar>(data, size)) specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0;
: 0;
return write_padded(out, specs, size, width, return write_padded(out, specs, size, width,
[=](reserve_iterator<OutputIt> it) { [=](reserve_iterator<OutputIt> it) {
return copy_str<Char>(data, data + size, it); return copy_str<Char>(data, data + size, it);
@ -1818,14 +1830,6 @@ OutputIt write(OutputIt out, monostate, basic_format_specs<Char> = {},
return out; return out;
} }
template <typename Char, typename OutputIt,
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
OutputIt write(OutputIt out, string_view value) {
auto it = reserve(out, value.size());
it = copy_str<Char>(value.begin(), value.end(), it);
return base_iterator(out, it);
}
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view<Char> value) { FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view<Char> value) {
auto it = reserve(out, value.size()); auto it = reserve(out, value.size());
@ -1881,7 +1885,7 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, T value,
locale_ref = {}) { locale_ref = {}) {
return specs.type && specs.type != 's' return specs.type && specs.type != 's'
? write(out, value ? 1 : 0, specs, {}) ? write(out, value ? 1 : 0, specs, {})
: write(out, string_view(value ? "true" : "false"), specs); : write_bytes(out, value ? "true" : "false", specs);
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>

View File

@ -128,7 +128,8 @@ template <typename Char> struct formatter<std::error_code, Char> {
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
-> decltype(ctx.out()) { -> decltype(ctx.out()) {
auto out = ctx.out(); auto out = ctx.out();
out = detail::write<Char>(out, to_string_view(ec.category().name())); out = detail::write_bytes(out, ec.category().name(),
basic_format_specs<Char>());
out = detail::write<Char>(out, Char(':')); out = detail::write<Char>(out, Char(':'));
out = detail::write<Char>(out, ec.value()); out = detail::write<Char>(out, ec.value());
return out; return out;

View File

@ -202,7 +202,7 @@ class printf_arg_formatter : public arg_formatter<Char> {
OutputIt write_null_pointer(bool is_string = false) { OutputIt write_null_pointer(bool is_string = false) {
auto s = this->specs; auto s = this->specs;
s.type = 0; 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: public: