Reduce library size

This commit is contained in:
Victor Zverovich
2020-04-29 09:21:25 -07:00
parent e2ff910675
commit 9ac1eebd47

View File

@ -1200,11 +1200,10 @@ template <typename Char> class float_writer {
} }
size_t size() const { return size_; } size_t size() const { return size_; }
size_t width() const { return size(); }
template <typename It> void operator()(It&& it) { template <typename It> It operator()(It it) const {
if (specs_.sign) *it++ = static_cast<Char>(data::signs[specs_.sign]); if (specs_.sign) *it++ = static_cast<Char>(data::signs[specs_.sign]);
it = prettify(it); return prettify(it);
} }
}; };
@ -1369,20 +1368,6 @@ class cstring_type_checker : public ErrorHandler {
FMT_CONSTEXPR void on_pointer() {} FMT_CONSTEXPR void on_pointer() {}
}; };
template <typename Char> struct nonfinite_writer {
sign_t sign;
const char* str;
static constexpr size_t str_size = 3;
size_t size() const { return str_size + (sign ? 1 : 0); }
size_t width() const { return size(); }
template <typename It> void operator()(It&& it) const {
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
it = copy_str<Char>(str, str + str_size, it);
}
};
template <typename OutputIt, typename Char> template <typename OutputIt, typename Char>
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) { FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) {
auto fill_size = fill.size(); auto fill_size = fill.size();
@ -1409,24 +1394,6 @@ template <typename Range> class basic_writer {
return internal::reserve(out_, n); return internal::reserve(out_, n);
} }
template <typename F> struct padded_int_writer {
size_t size_;
string_view prefix;
char_type fill;
std::size_t padding;
F f;
size_t size() const { return size_; }
size_t width() const { return size_; }
template <typename It> void operator()(It&& it) const {
if (prefix.size() != 0)
it = copy_str<char_type>(prefix.begin(), prefix.end(), it);
it = std::fill_n(it, padding, fill);
f(it);
}
};
// Writes an integer in the format // Writes an integer in the format
// <left-padding><prefix><numeric-padding><digits><right-padding> // <left-padding><prefix><numeric-padding><digits><right-padding>
// where <digits> are written by f(it). // where <digits> are written by f(it).
@ -1447,7 +1414,13 @@ template <typename Range> class basic_writer {
fill = static_cast<char_type>('0'); fill = static_cast<char_type>('0');
} }
if (specs.align == align::none) specs.align = align::right; if (specs.align == align::none) specs.align = align::right;
write_padded(specs, padded_int_writer<F>{size, prefix, fill, padding, f}); write_padded(specs, size, [=](reserve_iterator it) {
if (prefix.size() != 0)
it = copy_str<char_type>(prefix.begin(), prefix.end(), it);
it = std::fill_n(it, padding, fill);
f(it);
return it;
});
} }
// Writes a decimal integer. // Writes a decimal integer.
@ -1610,45 +1583,8 @@ template <typename Range> class basic_writer {
} }
}; };
template <typename Char> struct str_writer { using reserve_iterator = remove_reference_t<decltype(
const Char* s; internal::reserve(std::declval<iterator&>(), 0))>;
size_t size_;
size_t size() const { return size_; }
size_t width() const {
return count_code_points(basic_string_view<Char>(s, size_));
}
template <typename It> void operator()(It&& it) const {
it = copy_str<char_type>(s, s + size_, it);
}
};
struct bytes_writer {
string_view bytes;
size_t size() const { return bytes.size(); }
size_t width() const { return bytes.size(); }
template <typename It> void operator()(It&& it) const {
const char* data = bytes.data();
it = copy_str<char>(data, data + size(), it);
}
};
template <typename UIntPtr> struct pointer_writer {
UIntPtr value;
int num_digits;
size_t size() const { return to_unsigned(num_digits) + size_t(2); }
size_t width() const { return size(); }
template <typename It> void operator()(It&& it) const {
*it++ = static_cast<char_type>('0');
*it++ = static_cast<char_type>('x');
it = format_uint<4, char_type>(it, value, num_digits);
}
};
public: public:
explicit basic_writer(Range out, locale_ref loc = locale_ref()) explicit basic_writer(Range out, locale_ref loc = locale_ref())
@ -1659,24 +1595,30 @@ template <typename Range> class basic_writer {
// Writes a value in the format // Writes a value in the format
// <left-padding><value><right-padding> // <left-padding><value><right-padding>
// where <value> is written by f(it). // where <value> is written by f(it).
template <typename F> void write_padded(const format_specs& specs, F&& f) { template <typename F>
// User-perceived width (in code points). void write_padded(const format_specs& specs, size_t size, size_t width,
unsigned width = to_unsigned(specs.width); const F& f) {
size_t size = f.size(); // The number of code units. size_t padding = 0;
size_t num_code_points = width != 0 ? f.width() : size;
size_t padding = width > num_code_points ? width - num_code_points : 0;
size_t left_padding = 0; size_t left_padding = 0;
if (specs.align == align::right) if (unsigned spec_width = to_unsigned(specs.width)) {
left_padding = padding; padding = spec_width > width ? spec_width - width : 0;
else if (specs.align == align::center) if (specs.align == align::right)
left_padding = padding / 2; left_padding = padding;
else if (specs.align == align::center)
left_padding = padding / 2;
}
auto&& it = reserve(size + padding * specs.fill.size()); auto&& it = reserve(size + padding * specs.fill.size());
it = fill(it, left_padding, specs.fill); it = fill(it, left_padding, specs.fill);
// Dummy check to workaround a bug in MSVC2017. // Dummy check to workaround a bug in MSVC2017.
if (const_check(true)) f(it); if (const_check(true)) it = f(it);
it = fill(it, padding - left_padding, specs.fill); it = fill(it, padding - left_padding, specs.fill);
} }
template <typename F>
void write_padded(const format_specs& specs, size_t size, const F& f) {
write_padded(specs, size, size, f);
}
void write(int value) { write_decimal(value); } void write(int value) { write_decimal(value); }
void write(long value) { write_decimal(value); } void write(long value) { write_decimal(value); }
void write(long long value) { write_decimal(value); } void write(long long value) { write_decimal(value); }
@ -1712,7 +1654,13 @@ template <typename Range> class basic_writer {
if (!std::isfinite(value)) { if (!std::isfinite(value)) {
auto str = std::isinf(value) ? (fspecs.upper ? "INF" : "inf") auto str = std::isinf(value) ? (fspecs.upper ? "INF" : "inf")
: (fspecs.upper ? "NAN" : "nan"); : (fspecs.upper ? "NAN" : "nan");
return write_padded(specs, nonfinite_writer<char_type>{fspecs.sign, str}); constexpr size_t str_size = 3;
auto sign = fspecs.sign;
auto size = str_size + (sign ? 1 : 0);
return write_padded(specs, size, [=](reserve_iterator it) {
if (sign) *it++ = static_cast<char_type>(data::signs[sign]);
return copy_str<char_type>(str, str + str_size, it);
});
} }
if (specs.align == align::none) { if (specs.align == align::none) {
@ -1731,8 +1679,7 @@ template <typename Range> class basic_writer {
if (fspecs.format == float_format::hex) { if (fspecs.format == float_format::hex) {
if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]);
snprintf_float(promote_float(value), specs.precision, fspecs, buffer); snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
write_padded(specs, str_writer<char>{buffer.data(), buffer.size()}); return write_bytes({buffer.data(), buffer.size()}, specs);
return;
} }
int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
if (fspecs.format == float_format::exp) { if (fspecs.format == float_format::exp) {
@ -1752,9 +1699,9 @@ template <typename Range> class basic_writer {
fspecs.precision = precision; fspecs.precision = precision;
char_type point = fspecs.locale ? decimal_point<char_type>(locale_) char_type point = fspecs.locale ? decimal_point<char_type>(locale_)
: static_cast<char_type>('.'); : static_cast<char_type>('.');
write_padded(specs, float_writer<char_type>(buffer.data(), float_writer<char_type> w(buffer.data(), static_cast<int>(buffer.size()),
static_cast<int>(buffer.size()), exp, fspecs, point);
exp, fspecs, point)); write_padded(specs, w.size(), w);
} }
void write(char value) { void write(char value) {
@ -1780,7 +1727,12 @@ template <typename Range> class basic_writer {
template <typename Char> template <typename Char>
void write(const Char* s, std::size_t size, const format_specs& specs) { void write(const Char* s, std::size_t size, const format_specs& specs) {
write_padded(specs, str_writer<Char>{s, size}); auto width = specs.width != 0
? count_code_points(basic_string_view<Char>(s, size))
: 0;
write_padded(specs, size, width, [=](reserve_iterator it) {
return copy_str<char_type>(s, s + size, it);
});
} }
template <typename Char> template <typename Char>
@ -1793,17 +1745,25 @@ template <typename Range> class basic_writer {
} }
void write_bytes(string_view bytes, const format_specs& specs) { void write_bytes(string_view bytes, const format_specs& specs) {
write_padded(specs, bytes_writer{bytes}); write_padded(specs, bytes.size(), [bytes](reserve_iterator it) {
const char* data = bytes.data();
return copy_str<char_type>(data, data + bytes.size(), it);
});
} }
template <typename UIntPtr> template <typename UIntPtr>
void write_pointer(UIntPtr value, const format_specs* specs) { void write_pointer(UIntPtr value, const format_specs* specs) {
int num_digits = count_digits<4>(value); int num_digits = count_digits<4>(value);
auto pw = pointer_writer<UIntPtr>{value, num_digits}; auto size = to_unsigned(num_digits) + size_t(2);
if (!specs) return pw(reserve(to_unsigned(num_digits) + 2)); auto write = [=](reserve_iterator it) {
*it++ = static_cast<char_type>('0');
*it++ = static_cast<char_type>('x');
return format_uint<4, char_type>(it, value, num_digits);
};
if (!specs) return void(write(reserve(size)));
format_specs specs_copy = *specs; format_specs specs_copy = *specs;
if (specs_copy.align == align::none) specs_copy.align = align::right; if (specs_copy.align == align::none) specs_copy.align = align::right;
write_padded(specs_copy, pw); write_padded(specs_copy, size, write);
} }
}; };
@ -1829,14 +1789,16 @@ class arg_formatter_base {
char_type value; char_type value;
size_t size() const { return 1; } size_t size() const { return 1; }
size_t width() const { return 1; }
template <typename It> void operator()(It&& it) const { *it++ = value; } template <typename It> It operator()(It it) const {
*it++ = value;
return it;
}
}; };
void write_char(char_type value) { void write_char(char_type value) {
if (specs_) if (specs_)
writer_.write_padded(*specs_, char_writer{value}); writer_.write_padded(*specs_, 1, char_writer{value});
else else
writer_.write(value); writer_.write(value);
} }