This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] New stream buffer for cin, cout etc.


Hi,

This is an updated version of the stream buffer I proposed in February:

http://gcc.gnu.org/ml/libstdc++/2003-02/msg00248.html

The basic goals of this change are to
1) Improve syncronization between C++ and C io objects (cin/stdin,
   cout/stdout etc.)

2) Allow wcin to work with charsets other than ISO-8859-1 and subsets
   thereof.

3) Improve performance of cin, cout, cerr and clog in syncronized mode.

4) Ease maintenance of basic_filebuf.

These goals are achieved by using a stream buffer
__gnu_cxx::basic_stdiobuf (loosely based on the egcs extension stdiobuf),
which forwards all operations to the corresponding stdio functions. The
only code shared with basic_filebuf is __basic_file::showmanyc_helper,
which has been transformed into a global function __showmanyc_helper.

This design meets goals 1) and 2) trivially, as all iostream operations
are equivalent to the corresponding stdio functions since the former
delegate to the latter.

On my machine, the simple test
for (int i = 0; i < n; ++i)
  cout.rdbuf()->sputc('a');
runs about 3x faster with this stream buffer than with basic_filebuf on
current 3.4. The difference is much greater on tests that use sputn.

By using a separate stream buffer for syncronized streams,
basic_filebuf can be simplified substantially, as all the variables
named __testsync, and the code paths taken only when those variables
are true can be removed. In particular, the line
  _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
can be removed from basic_filebuf::_M_underflow. I believe this will
allow a fully generic implementation of basic_filebuf::underflow().

This is not quite complete yet, in particular seekoff and seekpos are
not implemented.

Questions? Comments?

Petur


2003-04-30  Petur Runolfsson  <peturr02@ru.is>

	PR libstdc++/9520
	PR libstdc++/9661
	PR libstdc++/9662
	* config/linker-map.gnu:  Add __showmanyc_helper.
	* libstdc++-v3/config/io/basic_file_stdio.cc
	(__basic_file<char>::showmanyc_helper):  Move implementation to ...
	(__showmanyc_helper):  this
	* include/Makefile.am (ext_headers):
	Add ext/stdiostream.h
	* include/ext/stdiostream.h:  New file.
	(basic_stdiobuf, basic_istdiostream, basic_ostdiostream,
	basic_iostdiostream):  New.
	* src/globals.cc (buf_cout, buf_cin, buf_cerr, buf_wcout,
	buf_wcin, buf_wcerr):  Remove.
	(buf_cout_sync, buf_cin_sync, buf_cerr_sync, buf_cout_unsync,
	buf_cin_unsync, buf_cerr_unsync, buf_wcout_sync, buf_wcin_sync,
	buf_wcerr_sync, buf_wcout_unsync, buf_wcin_unsync,
	buf_wcerr_unsync):  Define.
	* src/ios.cc (Init::Init, Init::~Init,
	Init::_S_ios_create_buffers, Init::_S_ios_destroy_buffers):
	Use different stream buffers after sync_with_stdio(false).

Index: libstdc++-v3/config/linker-map.gnu
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/config/linker-map.gnu,v
retrieving revision 1.1.1.4
diff -c -3 -p -r1.1.1.4 linker-map.gnu
*** libstdc++-v3/config/linker-map.gnu	24 Apr 2003 19:58:29 -0000	1.1.1.4
--- libstdc++-v3/config/linker-map.gnu	30 Apr 2003 22:26:07 -0000
*************** GLIBCPP_3.4 {
*** 56,61 ****
--- 56,62 ----
        std::__num_base::_S_format_int*;
        std::__num_base::_S_atoms_in;
        std::__num_base::_S_atoms_out;
+       std::__showmanyc_helper*;
        
        # Needed only when generic cpu's atomicity.h is in use.
        __gnu_cxx::_Atomic_add_mutex;
Index: libstdc++-v3/config/io/basic_file_stdio.cc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/config/io/basic_file_stdio.cc,v
retrieving revision 1.1.1.3
diff -c -3 -p -r1.1.1.3 basic_file_stdio.cc
*** libstdc++-v3/config/io/basic_file_stdio.cc	24 Apr 2003 19:58:34 -0000	1.1.1.3
--- libstdc++-v3/config/io/basic_file_stdio.cc	30 Apr 2003 22:07:29 -0000
***************
*** 61,66 ****
--- 61,69 ----
  
  namespace std 
  {
+   streamsize
+   __showmanyc_helper(FILE* __file, bool __stdio);
+ 
    // Definitions for __basic_file<char>.
    __basic_file<char>::__basic_file(__c_lock* /*__lock*/) 
    : _M_cfile(NULL), _M_cfile_created(false) { }
*************** namespace std 
*** 276,286 ****
  
    streamsize
    __basic_file<char>::showmanyc_helper(bool __stdio)
    {
  #ifdef FIONREAD
      // Pipes and sockets.    
      int __num = 0;
!     int __r = ioctl(this->fd(), FIONREAD, &__num);
      if (!__r && __num >= 0)
        return __num; 
  #endif    
--- 279,293 ----
  
    streamsize
    __basic_file<char>::showmanyc_helper(bool __stdio)
+   { return __showmanyc_helper(_M_cfile, __stdio); }
+ 
+   streamsize
+   __showmanyc_helper(FILE* __file, bool __stdio)
    {
  #ifdef FIONREAD
      // Pipes and sockets.    
      int __num = 0;
!     int __r = ioctl(fileno(__file), FIONREAD, &__num);
      if (!__r && __num >= 0)
        return __num; 
  #endif    
*************** namespace std 
*** 288,294 ****
  #ifdef _GLIBCPP_HAVE_POLL
      // Cheap test.
      struct pollfd __pfd[1];
!     __pfd[0].fd = this->fd();
      __pfd[0].events = POLLIN;
      if (poll(__pfd, 1, 0) <= 0)
        return 0;
--- 295,301 ----
  #ifdef _GLIBCPP_HAVE_POLL
      // Cheap test.
      struct pollfd __pfd[1];
!     __pfd[0].fd = fileno(__file);
      __pfd[0].events = POLLIN;
      if (poll(__pfd, 1, 0) <= 0)
        return 0;
*************** namespace std 
*** 297,308 ****
  #if defined(_GLIBCPP_HAVE_S_ISREG) || defined(_GLIBCPP_HAVE_S_IFREG)
      // Regular files.
      struct stat __buffer;
!     int __ret = fstat(this->fd(), &__buffer);
      if (!__ret && _GLIBCPP_ISREG(__buffer.st_mode))
        if (__stdio)
! 	return __buffer.st_size - ftell(_M_cfile);
        else
! 	return __buffer.st_size - lseek(this->fd(), 0, ios_base::cur);
  #endif
      return 0;
    }
--- 304,315 ----
  #if defined(_GLIBCPP_HAVE_S_ISREG) || defined(_GLIBCPP_HAVE_S_IFREG)
      // Regular files.
      struct stat __buffer;
!     int __ret = fstat(fileno(__file), &__buffer);
      if (!__ret && _GLIBCPP_ISREG(__buffer.st_mode))
        if (__stdio)
! 	return __buffer.st_size - ftell(__file);
        else
! 	return __buffer.st_size - lseek(fileno(__file), 0, ios_base::cur);
  #endif
      return 0;
    }
Index: libstdc++-v3/include/Makefile.am
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/include/Makefile.am,v
retrieving revision 1.1.1.4
diff -c -3 -p -r1.1.1.4 Makefile.am
*** libstdc++-v3/include/Makefile.am	24 Apr 2003 19:58:41 -0000	1.1.1.4
--- libstdc++-v3/include/Makefile.am	30 Apr 2003 08:30:32 -0000
*************** ext_headers = \
*** 217,222 ****
--- 217,223 ----
  	${ext_srcdir}/algorithm \
  	${ext_srcdir}/enc_filebuf.h \
  	${ext_srcdir}/stdio_filebuf.h \
+ 	${ext_srcdir}/stdiostream.h \
  	${ext_srcdir}/functional \
  	${ext_srcdir}/hash_map \
  	${ext_srcdir}/hash_set \
Index: libstdc++-v3/include/ext/stdiostream.h
===================================================================
RCS file: libstdc++-v3/include/ext/stdiostream.h
diff -N libstdc++-v3/include/ext/stdiostream.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/include/ext/stdiostream.h	30 Apr 2003 22:49:18 -0000
***************
*** 0 ****
--- 1,289 ----
+ // Iostreams wrapper for stdio FILE* -*- C++ -*-
+ 
+ // Copyright (C) 2003 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ /** @file ext/stdiostream.h
+  *  This file is a GNU extension to the Standard C++ Library.
+  */
+ 
+ #ifndef _EXT_STDIOSTREAM_H
+ #define _EXT_STDIOSTREAM_H
+ 
+ #pragma GCC system_header
+ #include <streambuf>
+ #include <istream>
+ #include <ostream>
+ #include <cstdio>
+ #ifdef _GLIBCPP_USE_WCHAR_T
+ #include <cwchar>
+ #endif
+ 
+ namespace std
+ {
+   // Needed by showmanyc
+   streamsize
+   __showmanyc_helper(FILE* __file, bool __stdio);
+ } // namespace std
+ 
+ namespace __gnu_cxx
+ {
+   template<typename _CharT>
+     class basic_stdiobuf;
+   typedef basic_stdiobuf<char> stdiobuf;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef basic_stdiobuf<wchar_t> wstdiobuf;
+ #endif
+ 
+   template<typename _CharT>
+     class basic_istdiostream;
+   typedef basic_istdiostream<char> istdiostream;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef basic_istdiostream<wchar_t> wistdiostream;
+ #endif
+ 
+   template<typename _CharT>
+     class basic_ostdiostream;
+   typedef basic_ostdiostream<char> ostdiostream;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef basic_ostdiostream<wchar_t> wostdiostream;
+ #endif
+ 
+   template<typename _CharT>
+     class basic_stdiostream;
+   typedef basic_stdiostream<char> stdiostream;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef basic_stdiostream<wchar_t> wstdiostream;
+ #endif
+ 
+   // basic_stdiobuf
+   // Minimal wrapper around FILE*
+   template<>
+     class basic_stdiobuf<char> : public std::basic_streambuf<char>
+     {
+     private:
+       std::FILE* const _M_file;
+ 
+     public:
+       explicit basic_stdiobuf(std::FILE* __file)
+       : _M_file(__file)
+       { }
+ 
+       std::FILE*
+       stdiofile() const
+       { return _M_file; }
+ 
+     protected:
+       virtual int_type
+       underflow()
+       {
+ 	int_type __c = std::getc(_M_file);
+ 	return std::ungetc(__c, _M_file);
+       }
+ 
+       virtual int_type
+       uflow()
+       { return std::getc(_M_file); }
+ 
+       virtual int_type
+       pbackfail(int_type __c = traits_type::eof())
+       { return std::ungetc(__c, _M_file); }
+ 
+       virtual std::streamsize
+       xsgetn(char_type* __s, std::streamsize __n)
+       { return std::fread(__s, 1, __n, _M_file); }
+ 
+       virtual std::streamsize
+       showmanyc()
+       { return std::__showmanyc_helper(_M_file, true); }
+ 
+       virtual int_type
+       overflow(int_type __c = traits_type::eof())
+       {
+ 	int_type __ret;
+ 	if (traits_type::eq_int_type(__c, traits_type::eof()))
+ 	  {
+ 	    if (std::fflush(_M_file))
+ 	      __ret = traits_type::eof();
+ 	    else
+ 	      __ret = traits_type::not_eof(__c);
+ 	  }
+ 	else
+ 	  __ret = std::putc(__c, _M_file);
+ 	return __ret;
+       }
+ 
+       virtual std::streamsize
+       xsputn(const char_type* __s, std::streamsize __n)
+       { return std::fwrite(__s, 1, __n, _M_file); }
+ 
+       virtual int
+       sync()
+       { return std::fflush(_M_file); }
+     };
+ 
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   template<>
+     class basic_stdiobuf<wchar_t> : public std::basic_streambuf<wchar_t>
+     {
+     private:
+       std::FILE* const _M_file;
+ 
+     public:
+       explicit basic_stdiobuf(std::FILE* __file)
+       : _M_file(__file)
+       { }
+ 
+       std::FILE*
+       stdiofile() const
+       { return _M_file; }
+ 
+     protected:
+       virtual int_type
+       underflow()
+       {
+ 	int_type __c = std::getwc(_M_file);
+ 	return std::ungetwc(__c, _M_file);
+       }
+ 
+       virtual int_type
+       uflow()
+       { return std::getwc(_M_file); }
+ 
+       virtual int_type
+       pbackfail(int_type __c = traits_type::eof())
+       { return std::ungetwc(__c, _M_file); }
+ 
+       virtual std::streamsize
+       xsgetn(char_type* __s, std::streamsize __n)
+       {
+ 	std::streamsize __ret = 0;
+ 	while (__n--)
+ 	  {
+ 	    int_type __c = std::getwc(_M_file);
+ 	    if (__c == WEOF)
+ 	      break;
+ 	    *__s++ = __c;
+ 	    ++__ret;
+ 	  }
+ 	return __ret;
+       }
+ 
+       virtual int_type
+       overflow(int_type __c = traits_type::eof())
+       {
+ 	int_type __ret;
+ 	if (traits_type::eq_int_type(__c, traits_type::eof()))
+ 	  {
+ 	    if (std::fflush(_M_file))
+ 	      __ret = traits_type::eof();
+ 	    else
+ 	      __ret = traits_type::not_eof(__c);
+ 	  }
+ 	else
+ 	  __ret = std::putwc(__c, _M_file);
+ 	return __ret;
+       }
+ 
+       virtual std::streamsize
+       xsputn(const char_type* __s, std::streamsize __n)
+       {
+ 	std::streamsize __ret = 0;
+ 	while (__n--)
+ 	  {
+ 	    if (std::putwc(*__s++, _M_file) == WEOF)
+ 	      break;
+ 	    ++__ret;
+ 	  }
+ 	return __ret;
+       }
+ 
+       virtual int
+       sync()
+       { return std::fflush(_M_file); }
+     };
+ #endif
+ 
+   template<typename _CharT>
+     class basic_istdiostream : public std::basic_istream<_CharT>
+     {
+     private:
+       typedef std::basic_istream<_CharT> __istream_type;
+       typedef basic_stdiobuf<_CharT> __stdiobuf_type;
+ 
+       basic_stdiobuf<_CharT> _M_buf;
+ 
+     public:
+       explicit basic_istdiostream(std::FILE* __file)
+       : __istream_type(&_M_buf), _M_buf(__file)
+       { }
+ 
+       __stdiobuf_type*
+       rdbuf() const
+       { return const_cast<__stdiobuf_type*>(&_M_buf); }
+     };
+ 
+   template<typename _CharT>
+     class basic_ostdiostream : public std::basic_ostream<_CharT>
+     {
+     private:
+       typedef std::basic_ostream<_CharT> __ostream_type;
+       typedef basic_stdiobuf<_CharT> __stdiobuf_type;
+ 
+       basic_stdiobuf<_CharT> _M_buf;
+ 
+     public:
+       explicit basic_ostdiostream(std::FILE* __file)
+       : __ostream_type(&_M_buf), _M_buf(__file)
+       { }
+ 
+       __stdiobuf_type*
+       rdbuf() const
+       { return const_cast<__stdiobuf_type*>(&_M_buf); }      
+     };
+ 
+   template<typename _CharT>
+     class basic_stdiostream : public std::basic_iostream<_CharT>
+     {
+     private:
+       typedef std::basic_iostream<_CharT> __iostream_type;
+       typedef basic_stdiobuf<_CharT> __stdiobuf_type;
+ 
+       basic_stdiobuf<_CharT> _M_buf;
+ 
+     public:
+       explicit basic_stdiostream(std::FILE* __file)
+       : __iostream_type(&_M_buf), _M_buf(__file)
+       { }
+ 
+       __stdiobuf_type*
+       rdbuf() const
+       { return const_cast<__stdiobuf_type*>(&_M_buf); }
+     };
+ } // namespace __gnu_cxx
+ 
+ #endif /* _EXT_STDIOSTREAM_H */
Index: libstdc++-v3/src/globals.cc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/src/globals.cc,v
retrieving revision 1.1.1.3
diff -c -3 -p -r1.1.1.3 globals.cc
*** libstdc++-v3/src/globals.cc	28 Apr 2003 21:16:34 -0000	1.1.1.3
--- libstdc++-v3/src/globals.cc	30 Apr 2003 22:07:43 -0000
***************
*** 32,37 ****
--- 32,38 ----
  #include <ostream>
  #include <locale>
  #include <ext/stdio_filebuf.h>
+ #include <ext/stdiostream.h>
  
  // On AIX, and perhaps other systems, library initialization order is
  // not guaranteed.  For example, the static initializers for the main
*************** namespace __gnu_cxx
*** 78,98 ****
  {
    using namespace std;
  
!   // Because <iostream> declares the standard streams to be [io]stream
!   // types instead of say [io]fstream types, it is also necessary to
!   // allocate the actual file buffers in this file.
    typedef char fake_filebuf[sizeof(stdio_filebuf<char>)]
    __attribute__ ((aligned(__alignof__(stdio_filebuf<char>))));
!   fake_filebuf buf_cout;
!   fake_filebuf buf_cin;
!   fake_filebuf buf_cerr;
  
  #ifdef _GLIBCPP_USE_WCHAR_T
    typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)]
    __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>))));
!   fake_wfilebuf buf_wcout;
!   fake_wfilebuf buf_wcin;
!   fake_wfilebuf buf_wcerr;
  #endif
  
    typedef char fake_locale_Impl[sizeof(locale::_Impl)]
--- 79,110 ----
  {
    using namespace std;
  
!   // We use different stream buffer types depending on whether
!   // ios_base::sync_with_stdio(false) has been called.
!   typedef char fake_stdiobuf[sizeof(stdiobuf)]
!   __attribute__ ((aligned(__alignof__(stdiobuf))));
!   fake_stdiobuf buf_cout_sync;
!   fake_stdiobuf buf_cin_sync;
!   fake_stdiobuf buf_cerr_sync;
! 
    typedef char fake_filebuf[sizeof(stdio_filebuf<char>)]
    __attribute__ ((aligned(__alignof__(stdio_filebuf<char>))));
!   fake_filebuf buf_cout_unsync;
!   fake_filebuf buf_cin_unsync;
!   fake_filebuf buf_cerr_unsync;
  
  #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef char fake_wstdiobuf[sizeof(wstdiobuf)]
+   __attribute__ ((aligned(__alignof__(wstdiobuf))));
+   fake_wstdiobuf buf_wcout_sync;
+   fake_wstdiobuf buf_wcin_sync;
+   fake_wstdiobuf buf_wcerr_sync;
+ 
    typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)]
    __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>))));
!   fake_wfilebuf buf_wcout_unsync;
!   fake_wfilebuf buf_wcin_unsync;
!   fake_wfilebuf buf_wcerr_unsync;
  #endif
  
    typedef char fake_locale_Impl[sizeof(locale::_Impl)]
Index: libstdc++-v3/src/ios.cc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.1.1.5
diff -c -3 -p -r1.1.1.5 ios.cc
*** libstdc++-v3/src/ios.cc	28 Apr 2003 21:16:34 -0000	1.1.1.5
--- libstdc++-v3/src/ios.cc	30 Apr 2003 22:07:43 -0000
***************
*** 38,55 ****
  #include <fstream>
  #include <bits/atomicity.h>
  #include <ext/stdio_filebuf.h>
  
  namespace __gnu_cxx
  {
    // Extern declarations for global objects in src/globals.cc.
!   extern stdio_filebuf<char> buf_cout;
!   extern stdio_filebuf<char> buf_cin;
!   extern stdio_filebuf<char> buf_cerr;
  
  #ifdef _GLIBCPP_USE_WCHAR_T
!   extern stdio_filebuf<wchar_t> buf_wcout;
!   extern stdio_filebuf<wchar_t> buf_wcin;
!   extern stdio_filebuf<wchar_t> buf_wcerr;
  #endif
  } // namespace __gnu_cxx
  
--- 38,64 ----
  #include <fstream>
  #include <bits/atomicity.h>
  #include <ext/stdio_filebuf.h>
+ #include <ext/stdiostream.h>
  
  namespace __gnu_cxx
  {
    // Extern declarations for global objects in src/globals.cc.
!   extern stdiobuf buf_cout_sync;
!   extern stdiobuf buf_cin_sync;
!   extern stdiobuf buf_cerr_sync;
! 
!   extern stdio_filebuf<char> buf_cout_unsync;
!   extern stdio_filebuf<char> buf_cin_unsync;
!   extern stdio_filebuf<char> buf_cerr_unsync;
  
  #ifdef _GLIBCPP_USE_WCHAR_T
!   extern wstdiobuf buf_wcout_sync;
!   extern wstdiobuf buf_wcin_sync;
!   extern wstdiobuf buf_wcerr_sync;
! 
!   extern stdio_filebuf<wchar_t> buf_wcout_unsync;
!   extern stdio_filebuf<wchar_t> buf_wcin_unsync;
!   extern stdio_filebuf<wchar_t> buf_wcerr_unsync;
  #endif
  } // namespace __gnu_cxx
  
*************** namespace std 
*** 161,188 ****
  
      // Create stream buffers for the standard streams and use those
      // buffers without destroying and recreating the streams.
!     new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size);
!     new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size);
!     new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size);
!     cout.rdbuf(&buf_cout);
!     cin.rdbuf(&buf_cin);
!     cerr.rdbuf(&buf_cerr);
!     clog.rdbuf(&buf_cerr);
      
  #ifdef _GLIBCPP_USE_WCHAR_T
!     new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size);
!     new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size);
!     new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size);
!     wcout.rdbuf(&buf_wcout);
!     wcin.rdbuf(&buf_wcin);
!     wcerr.rdbuf(&buf_wcerr);
!     wclog.rdbuf(&buf_wcerr);
  #endif
    }
  
    void
    ios_base::Init::_S_destroy_buffers()
    {
      // Explicitly call dtors to free any memory that is dynamically
      // allocated by filebuf ctor or member functions, but don't
      // deallocate all memory by calling operator delete.
--- 170,198 ----
  
      // Create stream buffers for the standard streams and use those
      // buffers without destroying and recreating the streams.
!     new (&buf_cout_unsync) stdio_filebuf<char>(stdout, ios_base::out, __out_size);
!     new (&buf_cin_unsync) stdio_filebuf<char>(stdin, ios_base::in, __in_size);
!     new (&buf_cerr_unsync) stdio_filebuf<char>(stderr, ios_base::out, __out_size);
!     cout.rdbuf(&buf_cout_unsync);
!     cin.rdbuf(&buf_cin_unsync);
!     cerr.rdbuf(&buf_cerr_unsync);
!     clog.rdbuf(&buf_cerr_unsync);
      
  #ifdef _GLIBCPP_USE_WCHAR_T
!     new (&buf_wcout_unsync) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size);
!     new (&buf_wcin_unsync) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size);
!     new (&buf_wcerr_unsync) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size);
!     wcout.rdbuf(&buf_wcout_unsync);
!     wcin.rdbuf(&buf_wcin_unsync);
!     wcerr.rdbuf(&buf_wcerr_unsync);
!     wclog.rdbuf(&buf_wcerr_unsync);
  #endif
    }
  
    void
    ios_base::Init::_S_destroy_buffers()
    {
+     /*
      // Explicitly call dtors to free any memory that is dynamically
      // allocated by filebuf ctor or member functions, but don't
      // deallocate all memory by calling operator delete.
*************** namespace std 
*** 195,200 ****
--- 205,211 ----
      buf_wcin.~stdio_filebuf();
      buf_wcerr.~stdio_filebuf();
  #endif
+     */
    }
  
    ios_base::Init::Init()
*************** namespace std 
*** 204,228 ****
  	// Standard streams default to synced with "C" operations.
  	ios_base::Init::_S_synced_with_stdio = true;
  
  	// The standard streams are constructed once only and never destroyed.
! 	// The stream buffers are set in _S_create_buffers below.
! 	new (&cout) ostream(NULL);
! 	new (&cin) istream(NULL);
! 	new (&cerr) ostream(NULL);
! 	new (&clog) ostream(NULL);
  	cin.tie(&cout);
  	cerr.flags(ios_base::unitbuf);
  	
  #ifdef _GLIBCPP_USE_WCHAR_T
! 	new (&wcout) wostream(NULL);
! 	new (&wcin) wistream(NULL);
! 	new (&wcerr) wostream(NULL);
! 	new (&wclog) wostream(NULL);
  	wcin.tie(&wcout);
  	wcerr.flags(ios_base::unitbuf);
  #endif
  
- 	_S_create_buffers(ios_base::Init::_S_synced_with_stdio);
  	_S_ios_base_init = 1;
        }
      ++_S_ios_base_init;
--- 215,245 ----
  	// Standard streams default to synced with "C" operations.
  	ios_base::Init::_S_synced_with_stdio = true;
  
+ 	new (&buf_cout_sync) stdiobuf(stdout);
+ 	new (&buf_cin_sync) stdiobuf(stdin);
+ 	new (&buf_cerr_sync) stdiobuf(stderr);
+ 
  	// The standard streams are constructed once only and never destroyed.
! 	new (&cout) ostream(&buf_cout_sync);
! 	new (&cin) istream(&buf_cin_sync);
! 	new (&cerr) ostream(&buf_cerr_sync);
! 	new (&clog) ostream(&buf_cerr_sync);
  	cin.tie(&cout);
  	cerr.flags(ios_base::unitbuf);
  	
  #ifdef _GLIBCPP_USE_WCHAR_T
! 	new (&buf_wcout_sync) wstdiobuf(stdout);
! 	new (&buf_wcin_sync) wstdiobuf(stdin);
! 	new (&buf_wcerr_sync) wstdiobuf(stderr);
! 
! 	new (&wcout) wostream(&buf_wcout_sync);
! 	new (&wcin) wistream(&buf_wcin_sync);
! 	new (&wcerr) wostream(&buf_wcerr_sync);
! 	new (&wclog) wostream(&buf_wcerr_sync);
  	wcin.tie(&wcout);
  	wcerr.flags(ios_base::unitbuf);
  #endif
  
  	_S_ios_base_init = 1;
        }
      ++_S_ios_base_init;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]