mirror of
https://github.com/fmtlib/fmt.git
synced 2026-10-29 02:17:28 +08:00
Optimize buffered padding with chunked fills
Fill available appender storage in bulk, continuing across buffer growth and flushes Preserve the constexpr-compatible scalar fallback Add testing of large padded sizes
This commit is contained in:
parent
5da4e9a3fb
commit
f34bffca73
@ -544,6 +544,20 @@ FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
|
||||
memset(out, value, to_unsigned(count));
|
||||
return out + count;
|
||||
}
|
||||
template <typename T>
|
||||
FMT_CONSTEXPR auto fill_n(basic_appender<T> out, size_t n, T value)
|
||||
-> basic_appender<T> {
|
||||
auto& buf = get_container(out);
|
||||
while (n != 0 && !is_constant_evaluated(true)) {
|
||||
buf.try_reserve(buf.size() + n);
|
||||
auto count = min_of(n, buf.capacity() - buf.size());
|
||||
auto ptr = buf.data() + buf.size();
|
||||
buf.try_resize(buf.size() + count);
|
||||
detail::fill_n(ptr, count, value);
|
||||
n -= count;
|
||||
}
|
||||
return fill_n<basic_appender<T>, size_t, T>(out, n, value);
|
||||
}
|
||||
|
||||
template <typename T, typename V, typename OutputIt>
|
||||
FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
|
||||
|
||||
@ -2254,6 +2254,7 @@ TEST(format_test, formatted_size) {
|
||||
#if FMT_USE_LOCALE
|
||||
EXPECT_EQ(2u, fmt::formatted_size(std::locale(), "{}", 42));
|
||||
#endif
|
||||
EXPECT_EQ(602u, fmt::formatted_size("[{:*>600}]", 42));
|
||||
}
|
||||
|
||||
TEST(format_test, format_to_no_args) {
|
||||
@ -2327,6 +2328,11 @@ TEST(format_test, format_to_n) {
|
||||
result = fmt::format_to_n(buffer, 3, "{}", std::string(1000, '*'));
|
||||
EXPECT_EQ(1000u, result.size);
|
||||
EXPECT_EQ("***x", fmt::string_view(buffer, 4));
|
||||
|
||||
result = fmt::format_to_n(buffer, 0, "{:!>600}", 42);
|
||||
EXPECT_EQ(600u, result.size);
|
||||
EXPECT_EQ(buffer, result.out);
|
||||
EXPECT_EQ("***x", fmt::string_view(buffer, 4));
|
||||
}
|
||||
|
||||
struct test_output_iterator {
|
||||
@ -2354,6 +2360,10 @@ TEST(format_test, format_to_n_output_iterator) {
|
||||
char buf[10] = {};
|
||||
fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42);
|
||||
EXPECT_STREQ(buf, "42");
|
||||
auto result = fmt::format_to_n(test_output_iterator{buf}, 3, "{:*>600}", 42);
|
||||
EXPECT_EQ(600u, result.size);
|
||||
EXPECT_EQ(buf + 3, result.out.data);
|
||||
EXPECT_STREQ(buf, "***");
|
||||
}
|
||||
|
||||
TEST(format_test, vformat_to) {
|
||||
|
||||
@ -82,6 +82,7 @@ TEST(xchar_test, format) {
|
||||
if (sizeof(wchar_t) == 4)
|
||||
EXPECT_EQ(fmt::format(fmt::runtime(L"{:𓀨>3}"), 42), L"𓀨42");
|
||||
EXPECT_EQ(fmt::format(L"{}c{}", L"ab", 1), L"abc1");
|
||||
EXPECT_EQ(std::wstring(600, L'\u03a9'), fmt::format(L"{:\u03a9>600}", L""));
|
||||
}
|
||||
|
||||
TEST(xchar_test, is_formattable) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user