This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Nathan's __copy_streambufs rewrote
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: libstdc++ at gcc dot gnu dot org
- Cc: bkoz <bkoz at redhat dot com>, Nathan Myers <ncm at cantrip dot org>
- Date: Fri, 02 May 2003 11:25:17 +0200
- Subject: [Patch] Nathan's __copy_streambufs rewrote
Hi,
Nathan provided the below, which I have only slightly tweaked
here and there and regression tested. Also did a few basic
performance sanity-checks.
Seems way cool to me! Short, conceptually clear, no horrible
__builtin_alloca!
Benjamin, do you like it?
Paolo.
///////////
2003-05-02 Nathan Myers <ncm@cantrip.org>
Paolo Carlini <pcarlini@unitus.it>
* include/bits/streambuf.tcc (__copy_streambufs): Rewrote.
diff -prN libstdc++-v3-orig/include/bits/streambuf.tcc libstdc++-v3/include/bits/streambuf.tcc
*** libstdc++-v3-orig/include/bits/streambuf.tcc Fri May 2 00:25:55 2003
--- libstdc++-v3/include/bits/streambuf.tcc Fri May 2 11:00:28 2003
*************** namespace std
*** 183,243 ****
__copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
basic_streambuf<_CharT, _Traits>* __sbin,
basic_streambuf<_CharT, _Traits>* __sbout)
! {
! typedef typename _Traits::int_type int_type;
!
streamsize __ret = 0;
try
{
! for (;;)
! {
! streamsize __xtrct;
! const ptrdiff_t __avail = __sbin->_M_in_end
! - __sbin->_M_in_cur;
! if (__avail)
{
! __xtrct = __sbout->sputn(__sbin->_M_in_cur, __avail);
! __ret += __xtrct;
! __sbin->_M_move_in_cur(__xtrct);
! if (__xtrct != __avail)
break;
}
! else
{
! streamsize __charsread;
! const size_t __size = __sbout->_M_out_end
! - __sbout->_M_out_cur;
! if (__size)
! {
! _CharT* __buf =
! static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
! * __size));
! // Since the next sputn cannot fail sgetn can be
! // safely used.
! __charsread = __sbin->sgetn(__buf, __size);
! __xtrct = __sbout->sputn(__buf, __charsread);
! }
! else
! {
! __xtrct = __charsread = 0;
! const int_type __c = __sbin->sgetc();
! if (!_Traits::eq_int_type(__c, _Traits::eof()))
! {
! ++__charsread;
! if (_Traits::eq_int_type(__sbout->overflow(__c),
! _Traits::eof()))
! break;
! ++__xtrct;
! __sbin->sbumpc();
! }
! }
! __ret += __xtrct;
! if (__xtrct != __charsread)
break;
}
! if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
! break;
! }
}
catch(exception& __fail)
{
--- 183,215 ----
__copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
basic_streambuf<_CharT, _Traits>* __sbin,
basic_streambuf<_CharT, _Traits>* __sbout)
! {
streamsize __ret = 0;
try
{
! typename _Traits::int_type __c = __sbin->sgetc();
! while (!_Traits::eq_int_type(__c, _Traits::eof()))
! {
! const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur;
! if (__n > 1)
{
! const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur,
! __n);
! __sbin->_M_move_in_cur(__wrote);
! __ret += __wrote;
! if (__wrote < __n)
break;
+ __c = __sbin->underflow();
}
! else
{
! __c = __sbout->sputc(_Traits::to_char_type(__c));
! if (_Traits::eq_int_type(__c, _Traits::eof()))
break;
+ ++__ret;
+ __c = __sbin->snextc();
}
! }
}
catch(exception& __fail)
{