fix: [imp] long string formatting output

This commit is contained in:
mutouyun 2022-12-04 19:07:55 +08:00 committed by 木头云
parent 163e9b9ae1
commit 8a79e9a86b
4 changed files with 59 additions and 51 deletions

View File

@ -15,19 +15,19 @@ void imp_fmt_string(benchmark::State &state) {
}
}
void imp_fmt_multi_string(benchmark::State &state) {
void imp_multi_fmt_string(benchmark::State &state) {
for (auto _ : state) {
std::ignore = imp::fmt("hello world.", "hello world.", "hello world.", "hello world.", "hello world.");
}
}
void fmt_format_string(benchmark::State &state) {
void fmt_fmt_string(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("hello world.hello world.hello world.hello world.hello world.");
}
}
void fmt_format_multi_string(benchmark::State &state) {
void fmt_multi_fmt_string(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}{}{}{}{}",
"hello world.", " hello world.", " hello world.", " hello world.", " hello world.");
@ -40,19 +40,19 @@ void imp_fmt_int(benchmark::State &state) {
}
}
void imp_fmt_multi_int(benchmark::State &state) {
void imp_multi_fmt_int(benchmark::State &state) {
for (auto _ : state) {
std::ignore = imp::fmt(654321, 654321, 654321, 654321, 654321);
}
}
void fmt_format_int(benchmark::State &state) {
void fmt_fmt_int(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}", 654321);
}
}
void fmt_format_multi_int(benchmark::State &state) {
void fmt_multi_fmt_int(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}{}{}{}{}", 654321, 654321, 654321, 654321, 654321);
}
@ -64,19 +64,19 @@ void imp_fmt_float(benchmark::State &state) {
}
}
void imp_fmt_multi_float(benchmark::State &state) {
void imp_multi_fmt_float(benchmark::State &state) {
for (auto _ : state) {
std::ignore = imp::fmt(654.321, 654.321, 654.321, 654.321, 654.321);
}
}
void fmt_format_float(benchmark::State &state) {
void fmt_fmt_float(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}", 654.321);
}
}
void fmt_format_multi_float(benchmark::State &state) {
void fmt_multi_fmt_float(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}{}{}{}{}", 654.321, 654.321, 654.321, 654.321, 654.321);
}
@ -88,7 +88,7 @@ void imp_fmt_chrono(benchmark::State &state) {
}
}
void fmt_format_chrono(benchmark::State &state) {
void fmt_fmt_chrono(benchmark::State &state) {
for (auto _ : state) {
std::ignore = fmt::format("{}", std::chrono::system_clock::now());
}
@ -97,18 +97,18 @@ void fmt_format_chrono(benchmark::State &state) {
} // namespace
BENCHMARK(imp_fmt_string);
BENCHMARK(fmt_format_string);
BENCHMARK(fmt_fmt_string);
BENCHMARK(imp_fmt_int);
BENCHMARK(fmt_format_int);
BENCHMARK(fmt_fmt_int);
BENCHMARK(imp_fmt_float);
BENCHMARK(fmt_format_float);
BENCHMARK(fmt_fmt_float);
BENCHMARK(imp_fmt_multi_string);
BENCHMARK(fmt_format_multi_string);
BENCHMARK(imp_fmt_multi_int);
BENCHMARK(fmt_format_multi_int);
BENCHMARK(imp_fmt_multi_float);
BENCHMARK(fmt_format_multi_float);
BENCHMARK(imp_multi_fmt_string);
BENCHMARK(fmt_multi_fmt_string);
BENCHMARK(imp_multi_fmt_int);
BENCHMARK(fmt_multi_fmt_int);
BENCHMARK(imp_multi_fmt_float);
BENCHMARK(fmt_multi_fmt_float);
BENCHMARK(imp_fmt_chrono);
BENCHMARK(fmt_format_chrono);
BENCHMARK(fmt_fmt_chrono);

View File

@ -35,9 +35,8 @@ public:
std::size_t capacity() noexcept;
void reset() noexcept;
bool finish() noexcept;
bool resize(std::size_t sz) noexcept;
span<char> buffer() noexcept;
bool expend(std::size_t sz) noexcept;
span<char> buffer(std::size_t sz) noexcept;
void expend(std::size_t sz) noexcept;
bool append(std::string const &str) noexcept;
};

View File

@ -111,17 +111,15 @@ span<char> fmt_of_float(span<char const> fstr, span<char const> const &l) {
template <typename A /*a fundamental or pointer type*/>
int sprintf(fmt_context &ctx, span<char const> const &sfmt, A a) {
for (;;) {
auto sbuf = ctx.buffer();
auto sz = std::snprintf(sbuf.data(), sbuf.size(), sfmt.data(), a);
for (int sz = -1;;) {
auto sbuf = ctx.buffer(sz + 1);
sz = std::snprintf(sbuf.data(), sbuf.size(), sfmt.data(), a);
if (sz <= 0) {
return sz;
}
if (sz < sbuf.size()) {
return ctx.expend(sz) ? sz : -1;
}
if (!ctx.resize(sz + 1)) {
return -1;
ctx.expend(sz);
return sz;
}
}
}
@ -165,38 +163,35 @@ bool fmt_context::finish() noexcept {
}
}
bool fmt_context::resize(std::size_t sz) noexcept {
span<char> fmt_context::buffer(std::size_t sz) noexcept {
LIBIMP_TRY {
if (sz < sbuf_.size()) {
return true;
}
joined_.resize(roundup(sz));
return true;
} LIBIMP_CATCH(...) {
return false;
}
}
span<char> fmt_context::buffer() noexcept {
if (offset_ < sbuf_.size()) {
if ((offset_ + sz) < sbuf_.size()) {
return make_span(sbuf_).subspan(offset_);
} else {
/// @remark switch the cache to std::string
joined_.assign(sbuf_.data(), offset_);
joined_.resize(roundup(offset_ + sz));
}
} else if ((offset_ + sz) >= joined_.size()) {
joined_.resize(roundup(offset_ + sz));
}
return {&joined_[offset_], joined_.size() - offset_};
} LIBIMP_CATCH(...) {
return {};
}
}
bool fmt_context::expend(std::size_t sz) noexcept {
if ((offset_ += sz) < sbuf_.size()) {
return true;
}
return (offset_ < joined_.size()) || resize(offset_);
void fmt_context::expend(std::size_t sz) noexcept {
offset_ += sz;
}
bool fmt_context::append(std::string const &str) noexcept {
if ((buffer().size() < str.size()) && !resize(offset_ + str.size())) {
auto sbuf = buffer(str.size());
if (sbuf.size() < str.size()) {
return false;
}
std::memcpy(buffer().data(), str.data(), str.size());
std::memcpy(sbuf.data(), str.data(), str.size());
offset_ += str.size();
return true;
}

View File

@ -92,9 +92,23 @@ TEST(fmt, to_string) {
}
TEST(fmt, fmt) {
/// @brief hello world
auto s = imp::fmt("hello", " ", "world", ".");
EXPECT_EQ(s, "hello world.");
/// @brief chrono
std::cout << imp::fmt('[', std::chrono::system_clock::now(), "] ", s) << "\n";
/// @brief long string
s = imp::fmt(imp::spec("1024")("hello world."));
EXPECT_EQ(s, " "
" "
" "
" "
" "
" "
" "
" hello world.");
}
namespace {