From: Benjamin Kosnik Date: Fri, 25 Jan 2002 06:36:32 +0000 (+0000) Subject: ostream_inserter_char.cc (test07): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3a9ebf3ced7a2fd1d4447918be5f36b39d061fae;p=gcc.git ostream_inserter_char.cc (test07): New. 2002-01-24 Benjamin Kosnik * testsuite/27_io/ostream_inserter_char.cc (test07): New. 2002-01-24 Benjamin Kosnik * 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. From-SVN: r49205 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 62a66d09844..2bc1a95fa1e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,19 @@ +2002-01-24 Benjamin Kosnik + + * testsuite/27_io/ostream_inserter_char.cc (test07): New. + +2002-01-24 Benjamin Kosnik + + * 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. + 2002-01-24 Phil Edwards * include/bits/stl_tempbuf.h (_Temporary_buffer): Add doxygen hook. diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h index cc393aaf311..f680a508206 100644 --- a/libstdc++-v3/include/bits/basic_ios.h +++ b/libstdc++-v3/include/bits/basic_ios.h @@ -1,6 +1,6 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2001, 2002 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 @@ -62,12 +62,11 @@ namespace std typedef num_get<_CharT, __istreambuf_iter> __numget_type; // Data members: - private: + protected: basic_ostream<_CharT, _Traits>* _M_tie; char_type _M_fill; iostate _M_exception; - protected: basic_streambuf<_CharT, _Traits>* _M_streambuf; iostate _M_streambuf_state; @@ -174,7 +173,7 @@ namespace std inline char_type fill(char_type __ch) { - char_type __old = _M_fill; + char_type __old = this->fill(); _M_fill = __ch; return __old; } @@ -198,14 +197,11 @@ namespace std init(basic_streambuf<_CharT, _Traits>* __sb); bool - _M_check_facet(const locale::facet* __f) + _M_check_facet(const locale::facet* __f) const { - bool __ret = false; - if (__f) - __ret = true; - else + if (!__f) __throw_bad_cast(); - return __ret; + return true; } void diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 47d940bd69c..d1f5d19b33c 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -1,6 +1,6 @@ // basic_ios locale and locale-related member functions -*- C++ -*- -// Copyright (C) 1999, 2001 Free Software Foundation, Inc. +// Copyright (C) 1999, 2001, 2002 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 @@ -91,12 +91,22 @@ namespace std template char basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const - { return _M_ios_fctype->narrow(__c, __dfault); } + { + char __ret; + if (_M_check_facet(_M_ios_fctype)) + __ret = _M_ios_fctype->narrow(__c, __dfault); + return __ret; + } template _CharT basic_ios<_CharT, _Traits>::widen(char __c) const - { return _M_ios_fctype->widen(__c); } + { + char_type __ret; + if (_M_check_facet(_M_ios_fctype)) + __ret = _M_ios_fctype->widen(__c); + return __ret; + } // Locales: template @@ -119,7 +129,19 @@ namespace std 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; @@ -131,15 +153,18 @@ namespace std { if (has_facet<__ctype_type>(__loc)) _M_ios_fctype = &use_facet<__ctype_type>(__loc); + else + _M_ios_fctype = 0; // Should be filled in by ostream and istream, respectively. if (has_facet<__numput_type>(__loc)) _M_fnumput = &use_facet<__numput_type>(__loc); + else + _M_fnumput = 0; if (has_facet<__numget_type>(__loc)) _M_fnumget = &use_facet<__numget_type>(__loc); + else + _M_fnumget = 0; } } // namespace std -#endif // _CPP_BITS_BASICIOS_TCC - - - +#endif diff --git a/libstdc++-v3/testsuite/27_io/ios_init.cc b/libstdc++-v3/testsuite/27_io/ios_init.cc index ef7cdf49586..8356448af9d 100644 --- a/libstdc++-v3/testsuite/27_io/ios_init.cc +++ b/libstdc++-v3/testsuite/27_io/ios_init.cc @@ -1,6 +1,6 @@ // 2001-06-05 Benjamin Kosnik -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -30,6 +30,7 @@ // 27.4.2.1.6 class ios_base::init #include +#include #include #include @@ -81,8 +82,58 @@ void test01() VERIFY( k1 == initial ); } +// 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.. + try + { + std::basic_ostringstream oss; + } + catch(...) + { + test = false; + } + + // 02: Calls basic_ios::init, which uses ctype.. + try + { + std::basic_string str; + std::basic_ostringstream 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 ); +} + int main() { test01(); + test02(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/ostream_inserter_char.cc b/libstdc++-v3/testsuite/27_io/ostream_inserter_char.cc index 5c000d950c2..e8c15588557 100644 --- a/libstdc++-v3/testsuite/27_io/ostream_inserter_char.cc +++ b/libstdc++-v3/testsuite/27_io/ostream_inserter_char.cc @@ -1,6 +1,6 @@ // 1999-08-16 bkoz -// Copyright (C) 2000, 1999 Free Software Foundation +// Copyright (C) 1999, 2000, 2002 Free Software Foundation // // 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 @@ -52,10 +52,7 @@ bool test01() f << str01; f.close(); -#ifdef DEBUG_ASSERT - assert(test); -#endif - + VERIFY( test ); return test; } @@ -92,11 +89,6 @@ bool test02(void) oss03 << str03; tmp = oss03.str(); VERIFY( tmp == "909909" ); - -#ifdef DEBUG_ASSERT - assert(test); -#endif - return test; } @@ -133,17 +125,12 @@ bool test03(void) oss03 << str03; tmp = oss03.str(); VERIFY( tmp == "909909" ); - -#ifdef DEBUG_ASSERT - assert(test); -#endif - return test; } // stringstream and large strings -bool test04() { - +bool test04() +{ bool test = true; std::string str_01; const std::string str_02("coltrane playing 'softly as a morning sunrise'"); @@ -166,11 +153,6 @@ bool test04() { VERIFY( oss_02.good() ); VERIFY( str_tmp != str_01 ); VERIFY( str_tmp.size() == 2390 ); - -#ifdef DEBUG_ASSERT - assert(test); -#endif - return test; } @@ -216,11 +198,6 @@ bool test05() str10 = sstr05.str(); VERIFY( str05 == str01 ); VERIFY( str10 == str01 ); - -#ifdef DEBUG_ASSERT - assert(test); -#endif - return test; } @@ -249,13 +226,69 @@ void test06() VERIFY( ostr2.str() == "blackalicious NIA " ); ostr2 << "4: deception (5:19)"; // should append to full string from above VERIFY( ostr2.str() == "blackalicious NIA 4: deception (5:19)" ); +} + +// Global counter, needs to be reset after use. +bool used; + +class gnu_ctype : public std::ctype +{ +protected: + char_type + do_widen(char c) const + { + used = true; + return std::ctype::do_widen(c); + } + + const char* + do_widen(const char* low, const char* high, char_type* dest) const + { + used = true; + return std::ctype::do_widen(low, high, dest); + } +}; -#ifdef DEBUG_ASSERT - assert(test); +// 27.6.2.5.4 - Character inserter template functions +// [lib.ostream.inserters.character] +void test07() +{ +#if _GLIBCPP_USE_WCHAR_T + using namespace std; + bool test = true; + + const char* buffer = "SFPL 5th floor, outside carrol, the Asian side"; + + wostringstream oss; + oss.imbue(locale(locale::classic(), new gnu_ctype)); + + // 1 + // template + // basic_ostream& operator<<(basic_ostream& out, + // const char* s); + used = false; + oss << buffer; + VERIFY( used ); // Only required for char_type != char + wstring str = oss.str(); + wchar_t c1 = oss.widen(buffer[0]); + VERIFY( str[0] == c1 ); + wchar_t c2 = oss.widen(buffer[1]); + VERIFY( str[1] == c2 ); + + // 2 + // template + // basic_ostream& operator<<(basic_ostream& out, + // char c); + used = false; + oss.str(wstring()); + oss << 'b'; + VERIFY( used ); // Only required for char_type != char + str = oss.str(); + wchar_t c3 = oss.widen('b'); + VERIFY( str[0] == c3 ); #endif } - int main() { test01(); @@ -264,5 +297,6 @@ int main() test04(); test05(); test06(); + test07(); return 0; }