From d266adf80559d2cfe1f7ef8f2462e3e7ffdd7c6b Mon Sep 17 00:00:00 2001 From: Michael Kasperovich Date: Tue, 24 Nov 2015 18:47:04 +0300 Subject: [PATCH] Implement custom stream buffer (#92) --- format.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/format.h b/format.h index 5f17a687..b5482ee5 100644 --- a/format.h +++ b/format.h @@ -38,6 +38,7 @@ #include #include #include +#include #ifndef FMT_USE_IOSTREAMS # define FMT_USE_IOSTREAMS 1 @@ -2087,6 +2088,11 @@ class BasicWriter { */ std::size_t size() const { return buffer_.size(); } + /** + Returns underlying buffer. + */ + Buffer& buffer() const { return buffer_; } + /** Returns a pointer to the output buffer content. No terminating null character is appended. @@ -2688,12 +2694,56 @@ class BasicArrayWriter : public BasicWriter { typedef BasicArrayWriter ArrayWriter; typedef BasicArrayWriter WArrayWriter; +template > +class basic_formatbuf : public std::basic_streambuf { + + typedef typename std::basic_streambuf::int_type int_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + using std::basic_streambuf::setp; + using std::basic_streambuf::pptr; + using std::basic_streambuf::pbase; + + Buffer& buffer_; + Elem* start_; + +public: + basic_formatbuf(Buffer& buffer) : buffer_(buffer), start_(&buffer[0]) { + + setp(start_, start_ + buffer_.capacity()); + } + + virtual int_type overflow(int_type _Meta = traits_type::eof()) { + + if (!traits_type::eq_int_type(_Meta, traits_type::eof())) { + + size_t size = pptr() - start_; + buffer_.resize(size); + buffer_.reserve(size * 2); + + start_ = &buffer_[0]; + start_[size] = traits_type::to_char_type(_Meta); + setp(start_+ size + 1, start_ + size * 2); + } + + return _Meta; + } + + size_t size() { + return pptr() - start_; + } +}; + // Formats a value. template void format(BasicFormatter &f, const Char *&format_str, const T &value) { - std::basic_ostringstream os; - os << value; - std::basic_string str = os.str(); + internal::MemoryBuffer buffer; + + basic_formatbuf format_buf(buffer); + std::basic_ostream output(&format_buf); + output << value; + + BasicStringRef str(format_buf.size() > 0 ? &buffer[0] : 0, format_buf.size()); internal::Arg arg = internal::MakeValue(str); arg.type = static_cast( internal::MakeValue::type(str));