From 1aa98f8b93abb7c67c7c65401b919b32c6c555b5 Mon Sep 17 00:00:00 2001 From: Roman-Koshelev <34384083+Roman-Koshelev@users.noreply.github.com> Date: Thu, 9 Sep 2021 18:10:29 +0300 Subject: [PATCH] Eliminate double copying in vformat_to_n (#2489) --- include/fmt/core.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/include/fmt/core.h b/include/fmt/core.h index cba989c3..6d4196a4 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -879,6 +879,46 @@ class iterator_buffer final : public Traits, public buffer { auto count() const -> size_t { return Traits::count() + this->size(); } }; +template +class iterator_buffer final : public fixed_buffer_traits, public buffer { + private: + T* out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + protected: + void grow(size_t) override { + if (this->size() == this->capacity()) flush(); + } + + void flush() { + size_t n = this->limit(this->size()); + if (this->data() == out_) { + out_ += n; + this->set(data_, buffer_size); + } + this->clear(); + } + + public: + explicit iterator_buffer(T* out, size_t n = buffer_size) + : fixed_buffer_traits(n), buffer(out, 0, n), out_(out) {} + iterator_buffer(iterator_buffer&& other) + : fixed_buffer_traits(other), buffer(std::move(other)), out_(other.out_) { + if (this->data() != out_) { + this->set(data_, buffer_size); + this->clear(); + } + } + ~iterator_buffer() { flush(); } + + auto out() -> T* { + flush(); + return out_; + } + auto count() const -> size_t { return fixed_buffer_traits::count() + this->size(); } +}; + template class iterator_buffer final : public buffer { protected: void grow(size_t) override {}