diff --git a/format.h b/format.h index 1d3dffbeb88b..91f16e7f38ce 100644 --- a/format.h +++ b/format.h @@ -38,6 +38,7 @@ #include #include #include +#include #ifndef FMT_USE_IOSTREAMS # define FMT_USE_IOSTREAMS 1 @@ -2628,12 +2629,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));