summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2002-01-25 06:36:32 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2002-01-25 06:36:32 +0000
commitda9b3b51a4e221a071d52186112357e6e0ce00c3 (patch)
tree147b43df3b19f4ab2a95375185b83cdba58dbace
parent8250ae22de60a5a6da47c1d02628a78dd689d251 (diff)
downloadgcc-da9b3b51a4e221a071d52186112357e6e0ce00c3.tar.gz
2002-01-24 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/27_io/ostream_inserter_char.cc (test07): New. 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49205 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/include/bits/basic_ios.h16
-rw-r--r--libstdc++-v3/include/bits/basic_ios.tcc39
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_init.cc53
-rw-r--r--libstdc++-v3/testsuite/27_io/ostream_inserter_char.cc94
5 files changed, 170 insertions, 48 deletions
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 <bkoz@redhat.com>
+
+ * testsuite/27_io/ostream_inserter_char.cc (test07): New.
+
+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.
+
2002-01-24 Phil Edwards <pme@gcc.gnu.org>
* 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<typename _CharT, typename _Traits>
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<typename _CharT, typename _Traits>
_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<typename _CharT, typename _Traits>
@@ -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 <bkoz@redhat.com>
-// 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 <fstream>
+#include <sstream>
#include <iostream>
#include <testsuite_hooks.h>
@@ -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<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 );
+}
+
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<wchar_t>
+{
+protected:
+ char_type
+ do_widen(char c) const
+ {
+ used = true;
+ return std::ctype<wchar_t>::do_widen(c);
+ }
+
+ const char*
+ do_widen(const char* low, const char* high, char_type* dest) const
+ {
+ used = true;
+ return std::ctype<wchar_t>::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<class charT, class traits>
+ // basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& 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<class charT, class traits>
+ // basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& 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;
}