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]

Re: PR 3983, basic_istringstream<unsigned char> fails



This issue keeps resurfacing in various forms. I should probably write 
something up and put it in the 27_io FAQ. 

Here's the first discussion:
2001-12-03
	_M_fill initialization in basic_ios::init
	http://gcc.gnu.org/ml/libstdc++/2001-12/msg00021.html
	http://gcc.gnu.org/ml/libstdc++/2001-12/msg00106.html
	http://gcc.gnu.org/ml/libstdc++/2001-12/msg00113.html
	http://gcc.gnu.org/ml/libstdc++/2001-12/msg00120.html

Here's a recent patch that addressed this:
2002-01-24  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/basic_ios.h (basic_ios::_M_check_facet): Make
	const, tweak.
	(basic_ios::fill(char_type)): Use fill().	
	* include/bits/basic_ios.tcc (basic_ios::widen): Use _M_check_facet.
	(basic_ios::narrow): Same.
	(basic_ios::_M_cache_facets): Explicitly set cached facets to zero
	if they are invalid.
	(basic_ios::init): Comment.
	* testsuite/27_io/ios_init.cc (test02): New.
	

Here's the comment:
  template<typename _CharT, typename _Traits>
    void
    basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb)
    {
      // NB: This may be called more than once on the same object.
      ios_base::_M_init();
      _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. This is not 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;
      _M_streambuf_state = __sb ? goodbit : badbit;
    }


Here's the test:
// 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
void test02() 
{
  bool test = true;

  // 01: Doesn't call basic_ios::init, which uses ctype<char_type>..
  try
    {
      std::basic_ostringstream<unsigned short> 	oss;
    }
  catch(...)
    { 
      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);

      // write
      const unsigned short us[4] = {1246, 433, 520, 0};
      oss.write(us, 4);

      // flush
      oss.flush();
    }
  catch(const std::bad_cast& obj)
    {
      test = true;
    }
  catch(...)
    {
      test = false;
    }
  VERIFY( test );
}



Basically, I don't see a way to make non-required facets work, given the
constraints imposed in the standard, as per above. I'm not quite sure if
this is a bug, or intentional. I might have also missed something: please
correct me if I'm wrong. I can ping the library list for clarificatin if
people think the unformatted input should really work with non-required
types. 

-benjamin


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