diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index 06b2217d216..614b347736b 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -195,7 +195,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ios_base::iostate __err = ios_base::goodbit; __try { - if (this->rdbuf()->sputn(__s, __n) != __n) + if (this->rdbuf()->__buffered_sputn(__s, __n) != __n) __err = ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) diff --git a/libstdc++-v3/include/bits/ostream_insert.h b/libstdc++-v3/include/bits/ostream_insert.h index 72eea8b1d05..650ea1afd9e 100644 --- a/libstdc++-v3/include/bits/ostream_insert.h +++ b/libstdc++-v3/include/bits/ostream_insert.h @@ -48,7 +48,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; - const streamsize __put = __out.rdbuf()->sputn(__s, __n); + const streamsize __put = __out.rdbuf()->__buffered_sputn(__s, __n); if (__put != __n) __out.setstate(__ios_base::badbit); } diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index 22464c4401c..7e803e4fc08 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -108,6 +108,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } + template + streamsize + basic_streambuf<_CharT, _Traits>:: + __buffered_sputn(const char_type* __s, streamsize __n) + { + const streamsize __buf_len = this->epptr() - this->pptr(); + if (__buf_len >= __n) + { + traits_type::copy(this->pptr(), __s, __n); + this->__safe_pbump(__n); + return __n; + } + else + return this->xsputn(__s, __n); + } + // Conceivably, this could be used to implement buffer-to-buffer // copies, if this was ever desired in an un-ambiguous way by the // standard. diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index e213104c4f4..a1a2277adc7 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -455,6 +455,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION sputn(const char_type* __s, streamsize __n) { return this->xsputn(__s, __n); } + /** + * @brief Entry point for all single-character output functions. + * @param __s A buffer read area. + * @param __n A count. + * + * Internal output function. + * + * + * Has the same effect as sputn(__s,__n), but attempts to use the + * existing buffer space rather than make a virtual call, if possible. + */ + streamsize + __buffered_sputn(const char_type* __s, streamsize __n); + protected: /** * @brief Base constructor.