Commit ac39fabb by Benjamin Kosnik

basic_ios.tcc (basic_ios::init): Set _M_fill to zero.


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

	* include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill to zero.
	Adjust comment.
	* 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.

From-SVN: r50076
parent 831c4e87
2002-02-26 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill to zero.
Adjust comment.
* 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.
2002-02-26 Loren Rittle <ljrittle@acm.org> 2002-02-26 Loren Rittle <ljrittle@acm.org>
* include/Makefile.am (thread_target_headers): Unconditionally * include/Makefile.am (thread_target_headers): Unconditionally
......
...@@ -64,7 +64,8 @@ namespace std ...@@ -64,7 +64,8 @@ namespace std
// Data members: // Data members:
protected: protected:
basic_ostream<_CharT, _Traits>* _M_tie; basic_ostream<_CharT, _Traits>* _M_tie;
char_type _M_fill; mutable char_type _M_fill;
mutable bool _M_fill_init;
iostate _M_exception; iostate _M_exception;
basic_streambuf<_CharT, _Traits>* _M_streambuf; basic_streambuf<_CharT, _Traits>* _M_streambuf;
...@@ -160,7 +161,14 @@ namespace std ...@@ -160,7 +161,14 @@ namespace std
char_type char_type
fill() const fill() const
{ return _M_fill; } {
if (!_M_fill_init)
{
_M_fill = this->widen(' ');
_M_fill_init = true;
}
return _M_fill;
}
char_type char_type
fill(char_type __ch) fill(char_type __ch)
......
...@@ -144,17 +144,20 @@ namespace std ...@@ -144,17 +144,20 @@ namespace std
_M_cache_facets(_M_ios_locale); _M_cache_facets(_M_ios_locale);
_M_tie = 0; _M_tie = 0;
// NB: The 27.4.4.1 Postconditions Table only specifies // NB: The 27.4.4.1 Postconditions Table specifies requirements
// requirements after basic_ios::init() has been called. As part // after basic_ios::init() has been called. As part of this,
// of this, fill() must return widen(' '), which needs an imbued // fill() must return widen(' ') any time after init() has been
// ctype facet of char_type to return without throwing an // called, which needs an imbued ctype facet of char_type to
// exception. Unfortunately, ctype<char_type> is not necessarily a // return without throwing an exception. Unfortunately,
// required facet, so streams with char_type != [char, wchar_t] // ctype<char_type> is not necessarily a required facet, so
// will not have it by default. However, because fill()'s // streams with char_type != [char, wchar_t] will not have it by
// signature is const, this data member cannot be lazily // default. Because of this, the correct value for _M_fill is
// initialized. Thus, thoughts of using a non-const helper // constructed on the first call of fill(). That way,
// function in ostream inserters is really besides the point. // unformatted input and output with non-required basic_ios
_M_fill = this->widen(' '); // instantiations is possible even without imbuing the expected
// ctype<char_type> facet.
_M_fill = 0;
_M_fill_init = false;
_M_exception = goodbit; _M_exception = goodbit;
_M_streambuf = __sb; _M_streambuf = __sb;
......
...@@ -83,10 +83,8 @@ void test01() ...@@ -83,10 +83,8 @@ void test01()
} }
// Non-required instantiations don't have the required facets inbued, // Non-required instantiations don't have the required facets inbued,
// by default, into the locale object. As such, basic_ios::init is // by default, into the locale object.
// required to return a bad_cast for the first use of fill() call.
// See 27.4.4.1 // See 27.4.4.1
class gnu_ios: public std::basic_ios<char> { }; class gnu_ios: public std::basic_ios<char> { };
void test02() void test02()
...@@ -94,6 +92,7 @@ void test02() ...@@ -94,6 +92,7 @@ void test02()
bool test = true; bool test = true;
// 01: Doesn't call basic_ios::init, which uses ctype<char_type>.. // 01: Doesn't call basic_ios::init, which uses ctype<char_type>..
// This should be unambiguously correct.
try try
{ {
gnu_ios gios; gnu_ios gios;
...@@ -103,15 +102,12 @@ void test02() ...@@ -103,15 +102,12 @@ void test02()
test = false; test = false;
} }
// 02: Calls basic_ios::init, which uses ctype<char_type>.. // 02: Calls basic_ios::init, which may call ctype<char_type>...
try try
{ {
std::basic_string<unsigned short> str; std::basic_string<unsigned short> str;
std::basic_ostringstream<unsigned short> oss(str); std::basic_ostringstream<unsigned short> oss(str);
// Shouldn't get this far.
test = false;
// Try each member functions for unformatted io. // Try each member functions for unformatted io.
// put // put
oss.put(324); oss.put(324);
...@@ -125,7 +121,9 @@ void test02() ...@@ -125,7 +121,9 @@ void test02()
} }
catch(const std::bad_cast& obj) catch(const std::bad_cast& obj)
{ {
// This is correct. // Should be able to do the above without calling fill() and
// forcing a call to widen...
test = false;
} }
catch(...) catch(...)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment