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]

[v3] delay _M_fill initialization



This delays the initialization of _M_fill untill the first call of
basic_ios::fill(). By doing this, things like basic_istream<unsigned
short> can use unformatted I/O without adding non-required facets to
the imbued locale.

As discussed.

tested x86/linux

2002-02-26  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill to zero.
	* include/bits/basic_ios.h (basic_ios::_M_fill): Make mutable.
	(basic_ios::_M_fill_init): New.
	(basic_ios::fill()): Deal with _M_fill lazily.
	Adjust comment. 
	* testsuite/27_io/ios_init.cc (test02): Adjust testcase.

Index: include/bits/basic_ios.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.10
diff -c -p -r1.10 basic_ios.h
*** basic_ios.h	2002/02/16 00:19:12	1.10
--- basic_ios.h	2002/02/27 00:41:55
*************** namespace std 
*** 64,70 ****
        // Data members:
      protected:
        basic_ostream<_CharT, _Traits>* 	_M_tie;
!       char_type 			_M_fill;
        iostate 				_M_exception;
  
        basic_streambuf<_CharT, _Traits>* _M_streambuf;
--- 64,71 ----
        // Data members:
      protected:
        basic_ostream<_CharT, _Traits>* 	_M_tie;
!       mutable char_type 		_M_fill;
!       mutable bool			_M_fill_init;
        iostate 				_M_exception;
  
        basic_streambuf<_CharT, _Traits>* _M_streambuf;
*************** namespace std 
*** 160,166 ****
  
        char_type 
        fill() const 
!       { return _M_fill; }
  
        char_type 
        fill(char_type __ch)
--- 161,174 ----
  
        char_type 
        fill() const 
!       {
! 	if (!_M_fill_init)
! 	  {
! 	    _M_fill = this->widen(' ');
! 	    _M_fill_init = true;
! 	  }
! 	return _M_fill; 
!       }
  
        char_type 
        fill(char_type __ch)
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.12
diff -c -p -r1.12 basic_ios.tcc
*** basic_ios.tcc	2002/02/26 04:55:47	1.12
--- basic_ios.tcc	2002/02/27 00:41:56
*************** namespace std
*** 144,160 ****
        _M_cache_facets(_M_ios_locale);
        _M_tie = 0;
  
!       // NB: The 27.4.4.1 Postconditions Table only specifies
!       // requirements after basic_ios::init() has been called. As part
!       // of this, fill() must return widen(' '), which needs an imbued
!       // ctype facet of char_type to return without throwing an
!       // exception. Unfortunately, ctype<char_type> is not necessarily a
!       // required facet, so streams with char_type != [char, wchar_t]
!       // will not have it by default. However, because fill()'s
!       // signature is const, this data member cannot be lazily
!       // initialized.  Thus, thoughts of using a non-const helper
!       // function in ostream inserters is really besides the point.
!       _M_fill = this->widen(' ');
  
        _M_exception = goodbit;
        _M_streambuf = __sb;
--- 144,163 ----
        _M_cache_facets(_M_ios_locale);
        _M_tie = 0;
  
!       // NB: The 27.4.4.1 Postconditions Table specifies requirements
!       // after basic_ios::init() has been called. As part of this,
!       // fill() must return widen(' ') any time after init() has been
!       // called, which needs an imbued ctype facet of char_type to
!       // return without throwing an exception. Unfortunately,
!       // ctype<char_type> is not necessarily a required facet, so
!       // streams with char_type != [char, wchar_t] will not have it by
!       // default. Because of this, the correct value for _M_fill is
!       // constructed on the first call of fill(). That way,
!       // unformatted input and output with non-required basic_ios
!       // instantiations is possible even without imbuing the expected
!       // ctype<char_type> facet.
!       _M_fill = 0;
!       _M_fill_init = false;
  
        _M_exception = goodbit;
        _M_streambuf = __sb;
Index: testsuite/27_io/ios_init.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/27_io/ios_init.cc,v
retrieving revision 1.5
diff -c -p -r1.5 ios_init.cc
*** ios_init.cc	2002/02/26 04:55:48	1.5
--- ios_init.cc	2002/02/27 00:41:59
*************** void test01()
*** 83,92 ****
  }
  
  // Non-required instantiations don't have the required facets inbued,
! // by default, into the locale object. As such, basic_ios::init is
! // required to return a bad_cast for the first use of fill() call.
  // See 27.4.4.1
- 
  class gnu_ios: public std::basic_ios<char> { };
  
  void test02() 
--- 83,90 ----
  }
  
  // Non-required instantiations don't have the required facets inbued,
! // by default, into the locale object.
  // See 27.4.4.1
  class gnu_ios: public std::basic_ios<char> { };
  
  void test02() 
*************** void test02() 
*** 94,99 ****
--- 92,98 ----
    bool test = true;
  
    // 01: Doesn't call basic_ios::init, which uses ctype<char_type>..
+   // This should be unambiguously correct.
    try
      {
        gnu_ios gios;
*************** void test02() 
*** 103,117 ****
        test = false; 
      }
  
!   // 02: Calls basic_ios::init, which uses ctype<char_type>..
    try
      {
        std::basic_string<unsigned short>        	str;
        std::basic_ostringstream<unsigned short> 	oss(str);
        
-       // Shouldn't get this far.
-       test = false; 
- 
        // Try each member functions for unformatted io.
        // put
        oss.put(324);
--- 102,113 ----
        test = false; 
      }
  
!   // 02: Calls basic_ios::init, which may call ctype<char_type>...
    try
      {
        std::basic_string<unsigned short>        	str;
        std::basic_ostringstream<unsigned short> 	oss(str);
        
        // Try each member functions for unformatted io.
        // put
        oss.put(324);
*************** void test02() 
*** 125,131 ****
      }
    catch(const std::bad_cast& obj)
      {
!       // This is correct.
      }
    catch(...)
      {
--- 121,129 ----
      }
    catch(const std::bad_cast& obj)
      {
!       // Should be able to do the above without calling fill() and
!       // forcing a call to widen...
!       test = false;
      }
    catch(...)
      {


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