This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3] delay _M_fill initialization
- From: Benjamin Kosnik <bkoz at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Tue, 26 Feb 2002 17:00:55 -0800
- Subject: [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(...)
{