diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 23cd2c47210..7ce18b38b13 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,50 @@ +2002-07-30 Benjamin Kosnik + Gabriel Dos Reis + + * include/bits/char_traits.h: Remove generic definitions. + * include/bits/streambuf_iterator.h (istreambuf_iterator): Use + eof, not -2. + * include/bits/istream.tcc (istream::readsome): Don't check + against eof, instead use constants. + (istream::sync): Same. + (istream::sentry::sentry): Use eq_int_type. + (istream::get): Same. + * include/bits/ostream.tcc: Change __pad to + __pad<_CharT, _Traits>::_S_pad. + * include/bits/locale_facets.h: Add __pad_traits generic and + ostreambuf_iterator specialization. + * include/bits/locale_facets.tcc: Change __pad into struct __pad + with a _CharT and _Traits template parameter and _S_pad static + member function. + * src/locale-inst.cc: Update __pad instantiations. + + * include/std/std_fstream.h: Declare _M_underflow_common + specializations. + * src/fstream.cc: New. Add _M_underflow_common specializations. + * include/bits/fstream.tcc (filebuf::close): Use traits_type. + (filebuf::_M_underflow_common(bool)): Remove generic version, as + sys_ungetc and custom int_types don't get along. + * include/std/std_streambuf.h: Add _M_pos. + * src/Makefile.am (sources): Add fstream.cc. + * src/Makefile.in: Regenerate. + + * testsuite/21_strings/capacity.cc: Add char_traits specializations. + * testsuite/22_locale/codecvt_members_unicode_char.cc: Same. + * testsuite/22_locale/codecvt_members_unicode_wchar_t.cc: Same. + * testsuite/22_locale/ctor_copy_dtor.cc: Same. + * testsuite/27_io/filebuf_virtuals.cc (test07): Move to... + * testsuite/27_io/filebuf.cc: ...here. + * testsuite/testsuite_hooks.h: Add gnu_char, gnu_int, char_traits + specialization for both. + * testsuite/27_io/streambuf.cc: Add instantiation test, + testsuite_hooks include. + * testsuite/27_io/istream.cc: Same. + * testsuite/27_io/ostream.cc: Same. + * testsuite/27_io/fstream.cc: Same. + * testsuite/27_io/stringstream.cc: Same. + * testsuite/27_io/filebuf.cc: Same. + * testsuite/27_io/stringbuf.cc: Same. + 2002-07-29 Alan Modra * config/cpu/powerpc/cpu_limits.h (__glibcpp_long_bits): Define. diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 48ca669afc4..a5fdfbef296 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -1,6 +1,7 @@ // Character Traits for use by standard string and iostream -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 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 @@ -57,82 +58,53 @@ namespace std struct char_traits { typedef _CharT char_type; - // Unsigned as wint_t in unsigned. + // Unsigned as wint_t is unsigned. typedef unsigned long int_type; typedef streampos pos_type; typedef streamoff off_type; typedef mbstate_t state_type; static void - assign(char_type& __c1, const char_type& __c2) - { __c1 = __c2; } + assign(char_type& __c1, const char_type& __c2); static bool - eq(const char_type& __c1, const char_type& __c2) - { return __c1 == __c2; } + eq(const char_type& __c1, const char_type& __c2); static bool - lt(const char_type& __c1, const char_type& __c2) - { return __c1 < __c2; } + lt(const char_type& __c1, const char_type& __c2); static int - compare(const char_type* __s1, const char_type* __s2, size_t __n) - { - for (size_t __i = 0; __i < __n; ++__i) - if (!eq(__s1[__i], __s2[__i])) - return lt(__s1[__i], __s2[__i]) ? -1 : 1; - return 0; - } + compare(const char_type* __s1, const char_type* __s2, size_t __n); static size_t - length(const char_type* __s) - { - const char_type* __p = __s; - while (*__p) ++__p; - return (__p - __s); - } + length(const char_type* __s); static const char_type* - find(const char_type* __s, size_t __n, const char_type& __a) - { - for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) - if (*__p == __a) return __p; - return 0; - } + find(const char_type* __s, size_t __n, const char_type& __a); static char_type* - move(char_type* __s1, const char_type* __s2, size_t __n) - { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + move(char_type* __s1, const char_type* __s2, size_t __n); static char_type* - copy(char_type* __s1, const char_type* __s2, size_t __n) - { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + copy(char_type* __s1, const char_type* __s2, size_t __n); static char_type* - assign(char_type* __s, size_t __n, char_type __a) - { - for (char_type* __p = __s; __p < __s + __n; ++__p) - assign(*__p, __a); - return __s; - } + assign(char_type* __s, size_t __n, char_type __a); static char_type - to_char_type(const int_type& __c) - { return char_type(__c); } + to_char_type(const int_type& __c); static int_type - to_int_type(const char_type& __c) { return int_type(__c); } + to_int_type(const char_type& __c); static bool - eq_int_type(const int_type& __c1, const int_type& __c2) - { return __c1 == __c2; } + eq_int_type(const int_type& __c1, const int_type& __c2); static int_type - eof() { return static_cast(-1); } + eof(); static int_type - not_eof(const int_type& __c) - { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + not_eof(const int_type& __c); }; diff --git a/libstdc++-v3/include/bits/fpos.h b/libstdc++-v3/include/bits/fpos.h index 3cb3e4b51a2..279e0ab16ba 100644 --- a/libstdc++-v3/include/bits/fpos.h +++ b/libstdc++-v3/include/bits/fpos.h @@ -105,7 +105,7 @@ namespace std bool operator!=(const fpos& __pos) const { return _M_off != __pos._M_off; } - + streamoff _M_position() const { return _M_off; } diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 5b7e8bf9eae..2caeb6e5e58 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -112,7 +112,8 @@ namespace std { const int_type __eof = traits_type::eof(); bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - if (__testput && _M_really_overflow(__eof) == __eof) + if (__testput + && traits_type::eq_int_type(_M_really_overflow(__eof), __eof)) return __ret; // NB: Do this here so that re-opened filebufs will be cool... @@ -155,96 +156,6 @@ namespace std _M_last_overflowed = false; return __ret; } - - template - typename basic_filebuf<_CharT, _Traits>::int_type - basic_filebuf<_CharT, _Traits>:: - _M_underflow_common(bool __bump) - { - int_type __ret = traits_type::eof(); - bool __testin = _M_mode & ios_base::in; - bool __testout = _M_mode & ios_base::out; - - if (__testin) - { - // Check for pback madness, and if so swich back to the - // normal buffers and jet outta here before expensive - // fileops happen... - if (_M_pback_init) - { - _M_pback_destroy(); - if (_M_in_cur < _M_in_end) - return traits_type::to_int_type(*_M_in_cur); - } - - // Sync internal and external buffers. - // NB: __testget -> __testput as _M_buf_unified here. - bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; - bool __testinit = _M_is_indeterminate(); - if (__testget) - { - if (__testout) - _M_really_overflow(); - else if (_M_in_cur != _M_filepos) - _M_file.seekoff(_M_in_cur - _M_filepos, - ios_base::cur, ios_base::in); - } - - if (__testinit || __testget) - { - const locale __loc = this->getloc(); - const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); - - streamsize __elen = 0; - streamsize __ilen = 0; - if (__cvt.always_noconv()) - { - __elen = _M_file.xsgetn(reinterpret_cast(_M_in_beg), - _M_buf_size); - __ilen = __elen; - } - else - { - char* __buf = static_cast(__builtin_alloca(_M_buf_size)); - __elen = _M_file.xsgetn(__buf, _M_buf_size); - - const char* __eend; - char_type* __iend; - __res_type __r = __cvt.in(_M_state_cur, __buf, - __buf + __elen, __eend, _M_in_beg, - _M_in_beg + _M_buf_size, __iend); - if (__r == codecvt_base::ok) - __ilen = __iend - _M_in_beg; - else - { - // Unwind. - __ilen = 0; - _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); - } - } - - if (0 < __ilen) - { - _M_set_determinate(__ilen); - if (__testout) - _M_out_cur = _M_in_cur; - __ret = traits_type::to_int_type(*_M_in_cur); - if (__bump) - _M_in_cur_move(1); - else if (_M_buf_size == 1) - { - // If we are synced with stdio, we have to unget the - // character we just read so that the file pointer - // doesn't move. - _M_file.sys_ungetc(*_M_in_cur); - _M_set_indeterminate(); - } - } - } - } - _M_last_overflowed = false; - return __ret; - } template typename basic_filebuf<_CharT, _Traits>::int_type diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index fc0adea69e3..798fd332b90 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -54,13 +54,14 @@ namespace std __int_type __c = __sb->sgetc(); if (__in._M_check_facet(__in._M_fctype)) - while (__c != __eof - && __in._M_fctype->is(ctype_base::space, __c)) + while (!traits_type::eq_int_type(__c, __eof) + && __in._M_fctype->is(ctype_base::space, + traits_type::to_char_type(__c))) __c = __sb->snextc(); #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS //195. Should basic_istream::sentry's constructor ever set eofbit? - if (__c == __eof) + if (traits_type::eq_int_type(__c, __eof)) __in.setstate(ios_base::eofbit); #endif } @@ -521,7 +522,7 @@ namespace std { __c = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 - if (__c != __eof) + if (!traits_type::eq_int_type(__c, __eof)) _M_gcount = 1; else this->setstate(ios_base::eofbit | ios_base::failbit); @@ -552,7 +553,7 @@ namespace std const int_type __eof = traits_type::eof(); int_type __bufval = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 - if (__bufval != __eof) + if (!traits_type::eq_int_type(__bufval, __eof)) { _M_gcount = 1; __c = traits_type::to_char_type(__bufval); @@ -588,13 +589,15 @@ namespace std __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); - while (_M_gcount + 1 < __n && __c != __eof && __c != __idelim) + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); __c = __sb->snextc(); ++_M_gcount; } - if (__c == __eof) + if (traits_type::eq_int_type(__c, __eof)) this->setstate(ios_base::eofbit); } catch(exception& __fail) @@ -627,14 +630,17 @@ namespace std const int_type __eof = traits_type::eof(); __streambuf_type* __this_sb = this->rdbuf(); int_type __c = __this_sb->sgetc(); + char_type __c2 = traits_type::to_char_type(__c); - while (__c != __eof && __c != __idelim - && (__sb.sputc(traits_type::to_char_type(__c)) != __eof)) + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) + && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) { ++_M_gcount; __c = __this_sb->snextc(); + __c2 = traits_type::to_char_type(__c); } - if (__c == __eof) + if (traits_type::eq_int_type(__c, __eof)) this->setstate(ios_base::eofbit); } catch(exception& __fail) @@ -667,17 +673,19 @@ namespace std __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); - while (_M_gcount + 1 < __n && __c != __eof && __c != __idelim) + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); __c = __sb->snextc(); ++_M_gcount; } - if (__c == __eof) + if (traits_type::eq_int_type(__c, __eof)) this->setstate(ios_base::eofbit); else { - if (__c == __idelim) + if (traits_type::eq_int_type(__c, __idelim)) { __sb->sbumpc(); ++_M_gcount; @@ -717,14 +725,16 @@ namespace std int_type __c = __sb->sgetc(); __n = min(__n, numeric_limits::max()); - while (_M_gcount < __n && __c !=__eof && __c != __delim) + while (_M_gcount < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) { __c = __sb->snextc(); ++_M_gcount; } - if (__c == __eof) + if (traits_type::eq_int_type(__c, __eof)) this->setstate(ios_base::eofbit); - else if (__c == __delim) + else if (traits_type::eq_int_type(__c, __delim)) { __sb->sbumpc(); ++_M_gcount; @@ -806,9 +816,8 @@ namespace std { try { - const int_type __eof = traits_type::eof(); streamsize __num = this->rdbuf()->in_avail(); - if (__num != static_cast(__eof)) + if (__num > 0) { __num = min(__num, __n); if (__num) @@ -843,7 +852,8 @@ namespace std { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); - if (!__sb || __sb->sputbackc(__c) == __eof) + if (!__sb + || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) this->setstate(ios_base::badbit); } catch(exception& __fail) @@ -873,7 +883,8 @@ namespace std { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); - if (!__sb || __eof == __sb->sungetc()) + if (!__sb + || traits_type::eq_int_type(__sb->sungetc(), __eof)) this->setstate(ios_base::badbit); } catch(exception& __fail) @@ -895,7 +906,7 @@ namespace std basic_istream<_CharT, _Traits>:: sync(void) { - int __ret = traits_type::eof(); + int __ret = -1; _M_gcount = 0; sentry __cerb(*this, true); if (__cerb) @@ -903,10 +914,13 @@ namespace std try { __streambuf_type* __sb = this->rdbuf(); - if (!__sb || __ret == __sb->pubsync()) - this->setstate(ios_base::badbit); - else - __ret = 0; + if (__sb) + { + if (__sb->pubsync() == -1) + this->setstate(ios_base::badbit); + else + __ret = 0; + } } catch(exception& __fail) { @@ -1186,16 +1200,18 @@ namespace std __streambuf_type* __sb = __in.rdbuf(); __int_type __c = __sb->sbumpc(); const __int_type __eof = _Traits::eof(); - __testdelim = __c == __idelim; + __testdelim = _Traits::eq_int_type(__c, __idelim); - while (__extracted <= __n && __c != __eof && !__testdelim) + while (__extracted <= __n + && !_Traits::eq_int_type(__c, __eof) + && !__testdelim) { __str += _Traits::to_char_type(__c); ++__extracted; __c = __sb->sbumpc(); - __testdelim = __c == __idelim; + __testdelim = _Traits::eq_int_type(__c, __idelim); } - if (__c == __eof) + if (_Traits::eq_int_type(__c, __eof)) __in.setstate(ios_base::eofbit); } if (!__extracted && !__testdelim) diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 241c4655dc2..159cecccdcb 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -55,6 +55,9 @@ namespace std # define _GLIBCPP_NUM_FACETS 14 #endif + template + struct __pad; + // 22.2.1.1 Template class ctype // Include host and configuration specific ctype enums for ctype_base. #include @@ -652,6 +655,7 @@ namespace std virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; @@ -697,6 +701,23 @@ namespace std template locale::id num_get<_CharT, _InIter>::id; +#if 0 + // Partial specialization for istreambuf_iterator, so can use traits_type. + template + class num_get<_CharT, istreambuf_iterator<_CharT> >; + + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + string& __xtrc) const; + + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + string& __xtrc, int& __base) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; +#endif + template class num_put : public locale::facet, public __num_base { diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index dea2fdfdac2..63e52c00585 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -94,6 +94,7 @@ namespace std _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, string& __xtrc) const { + typedef char_traits<_CharT> __traits_type; const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); const numpunct<_CharT>& __np = use_facet >(__loc); @@ -103,7 +104,8 @@ namespace std const char_type __minus = __ctype.widen('-'); int __pos = 0; char_type __c = *__beg; - if ((__c == __plus || __c == __minus) && __beg != __end) + if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) + && __beg != __end) { __xtrc += __ctype.narrow(__c, char()); ++__pos; @@ -113,7 +115,7 @@ namespace std // Next, strip leading zeros. const char_type __zero = __ctype.widen(_S_atoms[_M_zero]); bool __found_zero = false; - while (__c == __zero && __beg != __end) + while (__traits_type::eq(__c, __zero) && __beg != __end) { __c = *(++__beg); __found_zero = true; @@ -141,11 +143,10 @@ namespace std while (__beg != __end) { // Only look in digits. - typedef char_traits<_CharT> __traits_type; const char_type* __p = __traits_type::find(__watoms, 10, __c); // NB: strchr returns true for __c == 0x0 - if (__p && __c) + if (__p && !__traits_type::eq(__c, char_type())) { // Try first for acceptable digit; record it if found. ++__pos; @@ -153,7 +154,8 @@ namespace std ++__sep_pos; __c = *(++__beg); } - else if (__c == __sep && __check_grouping && !__found_dec) + else if (__traits_type::eq(__c, __sep) + && __check_grouping && !__found_dec) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. @@ -169,7 +171,7 @@ namespace std break; } } - else if (__c == __dec && !__found_dec) + else if (__traits_type::eq(__c, __dec) && !__found_dec) { // According to the standard, if no grouping chars are seen, // no grouping check is applied. Therefore __found_grouping @@ -181,7 +183,8 @@ namespace std __c = *(++__beg); __found_dec = true; } - else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E]) + else if ((__traits_type::eq(__c, __watoms[_M_e]) + || __traits_type::eq(__c, __watoms[_M_E])) && !__found_sci && __pos) { // Scientific notation. @@ -190,7 +193,8 @@ namespace std __c = *(++__beg); // Remove optional plus or minus sign, if they exist. - if (__c == __plus || __c == __minus) + if (__traits_type::eq(__c, __plus) + || __traits_type::eq(__c, __minus)) { ++__pos; __xtrc += __ctype.narrow(__c, char()); @@ -228,6 +232,7 @@ namespace std _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, string& __xtrc, int& __base) const { + typedef char_traits<_CharT> __traits_type; const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); const numpunct<_CharT>& __np = use_facet >(__loc); @@ -241,10 +246,13 @@ namespace std else __base = 10; - // First check for sign. + // First check for sign. int __pos = 0; char_type __c = *__beg; - if ((__c == __ctype.widen('+') || __c == __ctype.widen('-')) + const char_type __plus = __ctype.widen('+'); + const char_type __minus = __ctype.widen('-'); + + if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) && __beg != __end) { __xtrc += __ctype.narrow(__c, char()); @@ -259,7 +267,7 @@ namespace std if (__base == 10) { bool __found_zero = false; - while (__c == __zero && __beg != __end) + while (__traits_type::eq(__c, __zero) && __beg != __end) { __c = *(++__beg); __found_zero = true; @@ -270,7 +278,9 @@ namespace std ++__pos; if (__basefield == 0) { - if ((__c == __x || __c == __X) && __beg != __end) + if ((__traits_type::eq(__c, __x) + || __traits_type::eq(__c, __X)) + && __beg != __end) { __xtrc += __ctype.narrow(__c, char()); ++__pos; @@ -284,12 +294,13 @@ namespace std } else if (__base == 16) { - if (__c == __zero && __beg != __end) + if (__traits_type::eq(__c, __zero) && __beg != __end) { __xtrc += _S_atoms[_M_zero]; ++__pos; __c = *(++__beg); - if ((__c == __x || __c == __X) && __beg != __end) + if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X)) + && __beg != __end) { __xtrc += __ctype.narrow(__c, char()); ++__pos; @@ -316,11 +327,10 @@ namespace std const char_type __sep = __np.thousands_sep(); while (__beg != __end) { - typedef char_traits<_CharT> __traits_type; const char_type* __p = __traits_type::find(__watoms, __len, __c); // NB: strchr returns true for __c == 0x0 - if (__p && __c) + if (__p && !__traits_type::eq(__c, char_type())) { // Try first for acceptable digit; record it if found. __xtrc += _S_atoms[__p - __watoms]; @@ -328,7 +338,7 @@ namespace std ++__sep_pos; __c = *(++__beg); } - else if (__c == __sep && __check_grouping) + else if (__traits_type::eq(__c, __sep) && __check_grouping) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. @@ -394,7 +404,9 @@ namespace std // Parse bool values as alphanumeric else { - typedef basic_string<_CharT> __string_type; + typedef char_traits<_CharT> __traits_type; + typedef basic_string<_CharT> __string_type; + locale __loc = __io.getloc(); const numpunct<_CharT>& __np = use_facet >(__loc); const __string_type __true = __np.truename(); @@ -407,8 +419,10 @@ namespace std for (size_t __n = 0; __beg != __end; ++__n) { char_type __c = *__beg++; - bool __testf = __n <= __falsen ? __c == __falses[__n] : false; - bool __testt = __n <= __truen ? __c == __trues[__n] : false; + bool __testf = __n <= __falsen + ? __traits_type::eq(__c, __falses[__n]) : false; + bool __testt = __n <= __truen + ? __traits_type::eq(__c, __trues[__n]) : false; if (!(__testf || __testt)) { __err |= ios_base::failbit; @@ -708,6 +722,7 @@ namespace std _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, int __len) const { + typedef char_traits<_CharT> __traits_type; // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const locale __loc = __io.getloc(); @@ -723,7 +738,7 @@ namespace std // Replace decimal point. const _CharT* __p; const numpunct<_CharT>& __np = use_facet >(__loc); - if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.'))) + if (__p = __traits_type::find(__ws, __len, __ctype.widen('.'))) __ws[__p - __ws] = __np.decimal_point(); #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS @@ -744,7 +759,7 @@ namespace std // Tack on decimal part. if (__p) { - char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __traits_type::copy(__p2, __p, __len - __declen); __newlen += __len - __declen; } @@ -816,13 +831,15 @@ namespace std _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, int __len) const { + typedef char_traits<_CharT> __traits_type; // [22.2.2.2.2] Stage 3. streamsize __w = __io.width(); _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); if (__w > static_cast(__len)) { - __pad(__io, __fill, __ws2, __ws, __w, __len, true); + __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws, + __w, __len, true); __len = static_cast(__w); // Switch strings. __ws = __ws2; @@ -845,7 +862,7 @@ namespace std if ((__flags & ios_base::boolalpha) == 0) { unsigned long __uv = __v; - __s = _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv); + __s = _M_convert_int(__s, __io, __fill, 'u', char(), __uv); } else { @@ -866,14 +883,14 @@ namespace std _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const - { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); } + { return _M_convert_int(__s, __io, __fill, 'd', char(), __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const - { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); } + { return _M_convert_int(__s, __io, __fill, 'u', char(), __v); } #ifdef _GLIBCPP_USE_LONG_LONG template @@ -894,7 +911,7 @@ namespace std _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const - { return _M_convert_float(__s, __io, __fill, char_type(), __v); } + { return _M_convert_float(__s, __io, __fill, char(), __v); } template _OutIter @@ -915,7 +932,7 @@ namespace std __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); try { - __s = _M_convert_int(__s, __io, __fill, 'u', char_type(), + __s = _M_convert_int(__s, __io, __fill, 'u', char(), reinterpret_cast(__v)); __io.flags(__flags); } @@ -1591,7 +1608,7 @@ namespace std const _CharT** __names, size_t __indexlen, ios_base::iostate& __err) const { - typedef char_traits __traits_type; + typedef char_traits<_CharT> __traits_type; int* __matches = static_cast(__builtin_alloca(sizeof(int) * __indexlen)); size_t __nmatches = 0; size_t __pos = 0; @@ -1686,7 +1703,7 @@ namespace std do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - typedef char_traits __traits_type; + typedef char_traits<_CharT> __traits_type; locale __loc = __io.getloc(); __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __days[7]; @@ -1729,7 +1746,7 @@ namespace std do_get_monthname(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - typedef char_traits __traits_type; + typedef char_traits<_CharT> __traits_type; locale __loc = __io.getloc(); __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __months[12]; @@ -1996,22 +2013,31 @@ namespace std // internal-adjusted objects are padded according to the rules below // concerning 0[xX] and +-, otherwise, exactly as right-adjusted // ones are. - template - void - __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds, - const streamsize __newlen, const streamsize __oldlen, - const bool __num) - { - typedef _CharT char_type; - typedef _Traits traits_type; - typedef typename traits_type::int_type int_type; - - int_type __plen = static_cast(__newlen - __oldlen); - char_type* __pads = static_cast(__builtin_alloca(sizeof(char_type) * __plen)); - traits_type::assign(__pads, __plen, __fill); - char_type* __beg; - char_type* __end; + // NB: Of the two parameters, _CharT can be deduced from the + // function arguments. The other (_Traits) has to be explicitly specified. + template + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, + const streamsize __oldlen, const bool __num); + }; + + template + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, + const streamsize __oldlen, const bool __num) + { + size_t __plen = static_cast(__newlen - __oldlen); + _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen)); + _Traits::assign(__pads, __plen, __fill); + + _CharT* __beg; + _CharT* __end; size_t __mod = 0; size_t __beglen; //either __plen or __oldlen ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; @@ -2019,7 +2045,7 @@ namespace std if (__adjust == ios_base::left) { // Padding last. - __beg = const_cast(__olds); + __beg = const_cast<_CharT*>(__olds); __beglen = __oldlen; __end = __pads; } @@ -2030,12 +2056,14 @@ namespace std // Who came up with these rules, anyway? Jeeze. locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); - const char_type __minus = __ctype.widen('-'); - const char_type __plus = __ctype.widen('+'); - bool __testsign = __olds[0] == __minus || __olds[0] == __plus; - bool __testhex = __ctype.widen('0') == __olds[0] - && (__ctype.widen('x') == __olds[1] - || __ctype.widen('X') == __olds[1]); + const _CharT __minus = __ctype.widen('-'); + const _CharT __plus = __ctype.widen('+'); + bool __testsign = _Traits::eq(__olds[0], __minus) + || _Traits::eq(__olds[0], __plus); + + bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) + && (_Traits::eq(__ctype.widen('x'), __olds[1]) + || _Traits::eq(__ctype.widen('X'), __olds[1])); if (__testhex) { __news[0] = __olds[0]; @@ -2044,23 +2072,23 @@ namespace std __news += 2; __beg = __pads; __beglen = __plen; - __end = const_cast(__olds + __mod); + __end = const_cast<_CharT*>(__olds + __mod); } else if (__testsign) { - __news[0] = __olds[0] == __plus ? __plus : __minus; + _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus; ++__mod; ++__news; __beg = __pads; __beglen = __plen; - __end = const_cast(__olds + __mod); + __end = const_cast<_CharT*>(__olds + __mod); } else { // Padding first. __beg = __pads; __beglen = __plen; - __end = const_cast(__olds); + __end = const_cast<_CharT*>(__olds); } } else @@ -2068,23 +2096,11 @@ namespace std // Padding first. __beg = __pads; __beglen = __plen; - __end = const_cast(__olds); + __end = const_cast<_CharT*>(__olds); } - traits_type::copy(__news, __beg, __beglen); - traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod); - } - - // NB: Can't have default argument on non-member template, and - // num_put doesn't have a _Traits template parameter, so this - // forwarding template adds in the default template argument. - template - void - __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds, - const streamsize __newlen, const streamsize __oldlen, - const bool __num) - { - return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds, - __newlen, __oldlen, __num); + _Traits::copy(__news, __beg, __beglen); + _Traits::copy(__news + __beglen, __end, + __newlen - __beglen - __mod); } // Used by both numeric and monetary facets. @@ -2401,5 +2417,3 @@ namespace std } // namespace std #endif - - diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index ce90dafa209..e42eca29192 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -474,7 +474,8 @@ namespace std streamsize __len = 1; if (__w > __len) { - __pad(__out, __out.fill(), __pads, &__c, __w, __len, false); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + &__c, __w, __len, false); __len = __w; } __out.write(__pads, __len); @@ -509,7 +510,8 @@ namespace std streamsize __len = 1; if (__w > __len) { - __pad(__out, __out.fill(), __pads, &__c, __w, __len, false); + __pad::_S_pad(__out, __out.fill(), __pads, + &__c, __w, __len, false); __len = __w; } __out.write(__pads, __len); @@ -542,7 +544,8 @@ namespace std streamsize __len = static_cast(_Traits::length(__s)); if (__w > __len) { - __pad(__out, __out.fill(), __pads, __s, __w, __len, false); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + __s, __w, __len, false); __s = __pads; __len = __w; } @@ -590,7 +593,8 @@ namespace std if (__w > __len) { - __pad(__out, __out.fill(), __pads, __ws, __w, __len, false); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + __ws, __w, __len, false); __str = __pads; __len = __w; } @@ -628,7 +632,8 @@ namespace std if (__w > __len) { - __pad(__out, __out.fill(), __pads, __s, __w, __len, false); + __pad::_S_pad(__out, __out.fill(), __pads, + __s, __w, __len, false); __s = __pads; __len = __w; } @@ -668,7 +673,8 @@ namespace std #endif if (__w > __len) { - __pad(__out, __out.fill(), __pads, __s, __w, __len, false); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, __s, + __w, __len, false); __s = __pads; __len = __w; } diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc index fd56347a7a4..99eb6af125f 100644 --- a/libstdc++-v3/include/bits/sstream.tcc +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -184,7 +184,7 @@ namespace std if (_M_buf_size) { - off_type __pos = __sp._M_position(); + off_type __pos = __sp; // Use streamoff operator to do conversion. char_type* __beg = NULL; char_type* __end = NULL; bool __testin = (ios_base::in & _M_mode & __mode) != 0; diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 659caecb2af..152df9c6e4b 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -69,13 +69,13 @@ namespace std public: istreambuf_iterator() throw() - : _M_sbuf(0), _M_c(-2) { } + : _M_sbuf(0), _M_c(traits_type::eof()) { } istreambuf_iterator(istream_type& __s) throw() - : _M_sbuf(__s.rdbuf()), _M_c(-2) { } + : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } istreambuf_iterator(streambuf_type* __s) throw() - : _M_sbuf(__s), _M_c(-2) { } + : _M_sbuf(__s), _M_c(traits_type::eof()) { } // NB: The result of operator*() on an end of stream is undefined. char_type @@ -85,21 +85,25 @@ namespace std istreambuf_iterator& operator++() { - if (_M_sbuf && _M_sbuf->sbumpc() == traits_type::eof()) + const int_type __eof = traits_type::eof(); + if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) _M_sbuf = 0; else - _M_c = -2; + _M_c = __eof; return *this; } istreambuf_iterator operator++(int) { + const int_type __eof = traits_type::eof(); istreambuf_iterator __old = *this; - if (_M_sbuf && (__old._M_c = _M_sbuf->sbumpc()) == traits_type::eof()) + if (_M_sbuf + && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), + __eof)) _M_sbuf = 0; else - _M_c = -2; + _M_c = __eof; return __old; } @@ -110,8 +114,8 @@ namespace std equal(const istreambuf_iterator& __b) const { const int_type __eof = traits_type::eof(); - bool __thiseof = _M_get() == __eof; - bool __beof = __b._M_get() == __eof; + bool __thiseof = traits_type::eq_int_type(_M_get(), __eof); + bool __beof = traits_type::eq_int_type(__b._M_get(), __eof); return (__thiseof && __beof || (!__thiseof && !__beof)); } #endif @@ -120,13 +124,14 @@ namespace std int_type _M_get() const { - int_type __ret = traits_type::eof(); + const int_type __eof = traits_type::eof(); + int_type __ret = __eof; if (_M_sbuf) { - if (_M_c != static_cast(-2)) + if (!traits_type::eq_int_type(_M_c, __eof)) __ret = _M_c; else - if ((__ret = _M_sbuf->sgetc()) == traits_type::eof()) + if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof)) _M_sbuf = 0; } return __ret; diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h index fb95965a06a..c3861051d40 100644 --- a/libstdc++-v3/include/std/std_fstream.h +++ b/libstdc++-v3/include/std/std_fstream.h @@ -286,7 +286,16 @@ namespace std } }; + // Explicit specializations. + template<> + basic_filebuf::int_type + basic_filebuf::_M_underflow_common(bool __bump); + #ifdef _GLIBCPP_USE_WCHAR_T + template<> + basic_filebuf::int_type + basic_filebuf::_M_underflow_common(bool __bump); + #endif // 27.8.1.5 Template class basic_ifstream /** diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h index 14db73c07cc..ecd546e85a8 100644 --- a/libstdc++-v3/include/std/std_streambuf.h +++ b/libstdc++-v3/include/std/std_streambuf.h @@ -71,6 +71,7 @@ namespace std // Non-standard Types: typedef ctype __ctype_type; typedef basic_streambuf __streambuf_type; + typedef typename traits_type::state_type __state_type; friend class basic_ios; friend class basic_istream; @@ -132,6 +133,9 @@ namespace std char_type* _M_pback_end_save; bool _M_pback_init; + // Yet unused. + fpos<__state_type> _M_pos; + // Initializes pback buffers, and moves normal buffers to safety. // Assumptions: // _M_in_cur has already been moved back diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index 36c5dfd4b81..120841b1239 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -70,6 +70,7 @@ sources = \ concept-inst.cc \ ctype.cc \ ext-inst.cc \ + fstream.cc \ fstream-inst.cc \ functexcept.cc \ globals.cc \ diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index 585c861fd71..0ad606a8a00 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -175,6 +175,7 @@ sources = \ concept-inst.cc \ ctype.cc \ ext-inst.cc \ + fstream.cc \ fstream-inst.cc \ functexcept.cc \ globals.cc \ @@ -279,7 +280,7 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libstdc___la_OBJECTS = basic_file.lo bitset.lo c++locale.lo codecvt.lo \ collate.lo complex_io.lo concept-inst.lo ctype.lo ext-inst.lo \ -fstream-inst.lo functexcept.lo globals.lo io-inst.lo ios.lo \ +fstream.lo fstream-inst.lo functexcept.lo globals.lo io-inst.lo ios.lo \ istream-inst.lo limits.lo locale-inst.lo locale.lo localename.lo \ messages.lo misc-inst.lo monetary.lo numeric.lo ostream-inst.lo \ sstream-inst.lo stdexcept.lo stl-inst.lo streambuf-inst.lo \ diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 10f45eca0a0..5e6c6751bc4 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -420,15 +420,7 @@ namespace std bool __verify_grouping(const basic_string&, basic_string&); - template - void - __pad(ios_base&, char, char*, const char *, streamsize, - streamsize, const bool); - - template - void - __pad >(ios_base&, char, char*, const char *, - streamsize, streamsize, const bool); + template class __pad >; #ifdef _GLIBCPP_USE_WCHAR_T template @@ -440,29 +432,23 @@ namespace std __verify_grouping(const basic_string&, basic_string&); - template - void - __pad(ios_base&, wchar_t, wchar_t*, const wchar_t*, - streamsize, streamsize, const bool); - - template - void - __pad >(ios_base&, wchar_t, wchar_t*, - const wchar_t*, streamsize, - streamsize, const bool); -#endif // _GLIBCPP_USE_WCHAR_T + template class __pad >; +#endif template int - __convert_from_v(char*, const int, const char*, double, const __c_locale&, int); + __convert_from_v(char*, const int, const char*, double, + const __c_locale&, int); template int - __convert_from_v(char*, const int, const char*, long double, const __c_locale&, int); + __convert_from_v(char*, const int, const char*, long double, + const __c_locale&, int); template int - __convert_from_v(char*, const int, const char*, long, const __c_locale&, int); + __convert_from_v(char*, const int, const char*, long, + const __c_locale&, int); template int @@ -471,7 +457,8 @@ namespace std template int - __convert_from_v(char*, const int, const char*, long long, const __c_locale&, int); + __convert_from_v(char*, const int, const char*, long long, + const __c_locale&, int); template int diff --git a/libstdc++-v3/testsuite/21_strings/capacity.cc b/libstdc++-v3/testsuite/21_strings/capacity.cc index be209e07e0c..3c45b005017 100644 --- a/libstdc++-v3/testsuite/21_strings/capacity.cc +++ b/libstdc++-v3/testsuite/21_strings/capacity.cc @@ -36,6 +36,93 @@ template struct B { }; +// char_traits specialization +namespace std +{ + template<> + struct char_traits > + { + typedef A char_type; + // Unsigned as wint_t in unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { return char_type(); } + + static int_type + to_int_type(const char_type& __c) { return int_type(); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; +} // namespace std + void test01() { // 1 POD types : resize, capacity, reserve diff --git a/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_char.cc b/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_char.cc index 0d0d1d5bcad..51bf9b9600a 100644 --- a/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_char.cc +++ b/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_char.cc @@ -23,10 +23,71 @@ #include #include -using namespace std; + #ifdef _GLIBCPP_USE___ENC_TRAITS +// Need some char_traits specializations for this to work. +typedef unsigned short unicode_t; + +namespace std +{ + template<> + struct char_traits + { + typedef unicode_t char_type; + // Unsigned as wint_t is unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c); + + static int_type + to_int_type(const char_type& __c); + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof(); + + static int_type + not_eof(const int_type& __c); + }; +} + /* > how do I check that these conversions are correct? Very easy. Since all the characters are from ASCII you simply @@ -51,7 +112,7 @@ it shows that the other byte-order is used (25856 == 0x6500). void -initialize_state(__enc_traits& state) +initialize_state(std::__enc_traits& state) { state._M_init(); } // Partial specialization using __enc_traits. @@ -59,8 +120,8 @@ initialize_state(__enc_traits& state) // UNICODE - UCS2 (big endian) void test01() { + using namespace std; typedef codecvt_base::result result; - typedef unsigned short unicode_t; typedef unicode_t int_type; typedef char ext_type; typedef __enc_traits enc_type; @@ -146,6 +207,7 @@ void test01() // UNICODE - UCS2 (little endian) void test02() { + using namespace std; typedef codecvt_base::result result; typedef unsigned short unicode_t; typedef unicode_t int_type; diff --git a/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_wchar_t.cc index 87a2f05bf6c..c944865b08f 100644 --- a/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_wchar_t.cc +++ b/libstdc++-v3/testsuite/22_locale/codecvt_members_unicode_wchar_t.cc @@ -1,6 +1,6 @@ // 2000-08-23 Benjamin Kosnik -// Copyright (C) 2000, 2001 Free Software Foundation +// Copyright (C) 2000, 2001, 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 @@ -23,21 +23,80 @@ #include #include -using namespace std; - #ifdef _GLIBCPP_USE___ENC_TRAITS #ifdef _GLIBCPP_USE_WCHAR_T +// Need some char_traits specializations for this to work. +typedef unsigned short unicode_t; + +namespace std +{ + template<> + struct char_traits + { + typedef unicode_t char_type; + // Unsigned as wint_t is unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c); + + static int_type + to_int_type(const char_type& __c); + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof(); + + static int_type + not_eof(const int_type& __c); + }; +} + void -initialize_state(__enc_traits& state) +initialize_state(std::__enc_traits& state) { state._M_init(); } // Partial specialization using __enc_traits. // codecvt void test01() { + using namespace std; typedef codecvt_base::result result; - typedef unsigned short unicode_t; typedef unicode_t int_type; typedef wchar_t ext_type; typedef __enc_traits enc_type; diff --git a/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc b/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc index 732ec1714aa..94db3bcc139 100644 --- a/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc +++ b/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc @@ -48,11 +48,70 @@ public: std::locale::id gnu_facet::id; +// Need some char_traits specializations for this to work. +typedef unsigned short unicode_t; + +namespace std +{ + template<> + struct char_traits + { + typedef unicode_t char_type; + // Unsigned as wint_t is unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c); + + static int_type + to_int_type(const char_type& __c); + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof(); + + static int_type + not_eof(const int_type& __c); + }; +} + void test01() { using namespace std; - - typedef unsigned short unicode_t; typedef unicode_t int_type; typedef char ext_type; typedef __enc_traits enc_type; diff --git a/libstdc++-v3/testsuite/27_io/filebuf.cc b/libstdc++-v3/testsuite/27_io/filebuf.cc index 9919365a552..e72f2ca8f6f 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf.cc @@ -42,11 +42,67 @@ void test01() // test05 // libstdc++/1886 // should be able to instantiate basic_filebuf for non-standard types. -template class std::basic_filebuf >; +namespace test +{ + using namespace std; + typedef short type_t; + template class basic_filebuf >; + template class basic_filebuf >; +} // test + + +// test07 +// libstdc++/2020 +// should be able to use custom char_type +class gnu_char_type +{ + unsigned long character; +public: + // operator == + bool + operator==(const gnu_char_type& __lhs) + { return character == __lhs.character; } + + // operator < + bool + operator<(const gnu_char_type& __lhs) + { return character < __lhs.character; } + + // default ctor + gnu_char_type() { } + + // to_char_type + gnu_char_type(const unsigned long& __l) : character(__l) { } + + // to_int_type + operator unsigned long() const { return character; } +}; + +void test07() +{ + bool test = true; + typedef std::basic_filebuf gnu_filebuf; + + try + { gnu_filebuf obj; } + catch(std::exception& obj) + { + test = false; + VERIFY( test ); + } +} + +#if !__GXX_WEAK__ +// Explicitly instantiate for systems with no COMDAT or weak support. +template + std::basic_streambuf::int_type + std::basic_streambuf::_S_pback_size; +#endif int main() { test01(); + test07(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc index fb370c36e50..0a92788296a 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc @@ -514,54 +514,6 @@ void test06() VERIFY( buffer[0] == 'a' ); } -// test06 -// libstdc++/2020 -// should be able to use custom char_type -class gnu_char_type -{ - unsigned long character; -public: - // operator == - bool - operator==(const gnu_char_type& __lhs) - { return character == __lhs.character; } - - // operator < - bool - operator<(const gnu_char_type& __lhs) - { return character < __lhs.character; } - - // default ctor - gnu_char_type() { } - - // to_char_type - gnu_char_type(const unsigned long& __l) : character(__l) { } - - // to_int_type - operator unsigned long() const { return character; } -}; - -void test07() -{ - bool test = true; - typedef std::basic_filebuf gnu_filebuf; - - try - { gnu_filebuf obj; } - catch(std::exception& obj) - { - test = false; - VERIFY( test ); - } -} - -#if !__GXX_WEAK__ -// Explicitly instantiate for systems with no COMDAT or weak support. -template - std::basic_streambuf::int_type - std::basic_streambuf::_S_pback_size; -#endif - main() { test01(); @@ -571,7 +523,6 @@ main() test04(); test05(); test06(); - test07(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/fstream.cc b/libstdc++-v3/testsuite/27_io/fstream.cc index 2ecd0778700..276294d9c9d 100644 --- a/libstdc++-v3/testsuite/27_io/fstream.cc +++ b/libstdc++-v3/testsuite/27_io/fstream.cc @@ -31,6 +31,7 @@ // NB: This file is for testing basic_fstream with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_fstream >; + template class basic_fstream >; } // test int main() diff --git a/libstdc++-v3/testsuite/27_io/ios_init.cc b/libstdc++-v3/testsuite/27_io/ios_init.cc index 1905aa64ac8..33a52de9470 100644 --- a/libstdc++-v3/testsuite/27_io/ios_init.cc +++ b/libstdc++-v3/testsuite/27_io/ios_init.cc @@ -34,6 +34,176 @@ #include #include +// char_traits specialization +namespace std +{ + template<> + struct char_traits + { + typedef unsigned short char_type; + // Unsigned as wint_t in unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { return char_type(); } + + static int_type + to_int_type(const char_type& __c) { return int_type(); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; + + template<> + struct char_traits + { + typedef unsigned char char_type; + // Unsigned as wint_t in unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p && *__p) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { return char_type(); } + + static int_type + to_int_type(const char_type& __c) { return int_type(); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; +} // namespace std + class gnu_filebuf: public std::filebuf { int i; diff --git a/libstdc++-v3/testsuite/27_io/istream.cc b/libstdc++-v3/testsuite/27_io/istream.cc index 05db50ed461..6cec904eb67 100644 --- a/libstdc++-v3/testsuite/27_io/istream.cc +++ b/libstdc++-v3/testsuite/27_io/istream.cc @@ -31,6 +31,7 @@ // NB: This file is for testing istream with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_istream >; + template class basic_istream >; } // test int main() diff --git a/libstdc++-v3/testsuite/27_io/ostream.cc b/libstdc++-v3/testsuite/27_io/ostream.cc index ae524ec61f2..ee764f9d697 100644 --- a/libstdc++-v3/testsuite/27_io/ostream.cc +++ b/libstdc++-v3/testsuite/27_io/ostream.cc @@ -31,6 +31,7 @@ // NB: This file is for testing ostream with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_ostream >; + template class basic_ostream >; } // test int main() diff --git a/libstdc++-v3/testsuite/27_io/streambuf.cc b/libstdc++-v3/testsuite/27_io/streambuf.cc index 905dee089de..102ff60c260 100644 --- a/libstdc++-v3/testsuite/27_io/streambuf.cc +++ b/libstdc++-v3/testsuite/27_io/streambuf.cc @@ -31,6 +31,7 @@ // NB: This file is for testing basic_streambuf with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_streambuf >; + template class basic_streambuf >; } // test int main() diff --git a/libstdc++-v3/testsuite/27_io/stringbuf.cc b/libstdc++-v3/testsuite/27_io/stringbuf.cc index 00825b6b69c..3cfd5af605c 100644 --- a/libstdc++-v3/testsuite/27_io/stringbuf.cc +++ b/libstdc++-v3/testsuite/27_io/stringbuf.cc @@ -31,6 +31,7 @@ // NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_stringbuf >; + template class basic_stringbuf >; } // test int main() diff --git a/libstdc++-v3/testsuite/27_io/stringstream.cc b/libstdc++-v3/testsuite/27_io/stringstream.cc index 1a1b0178074..cb9e39d9588 100644 --- a/libstdc++-v3/testsuite/27_io/stringstream.cc +++ b/libstdc++-v3/testsuite/27_io/stringstream.cc @@ -31,6 +31,7 @@ // NB: This file is for testing basic_stringstream with NO OTHER INCLUDES. #include +#include // { dg-do compile } @@ -51,6 +52,7 @@ namespace test using namespace std; typedef short type_t; template class basic_stringstream >; + template class basic_stringstream >; } // test int main() diff --git a/libstdc++-v3/testsuite/testsuite_hooks.h b/libstdc++-v3/testsuite/testsuite_hooks.h index a4be70a9b23..5725debe7e8 100644 --- a/libstdc++-v3/testsuite/testsuite_hooks.h +++ b/libstdc++-v3/testsuite/testsuite_hooks.h @@ -50,10 +50,16 @@ // 4) gnu_copy_tracker, from Stephen M. Webb . // A class with nontrivial ctor/dtor that provides the ability to track the // number of copy ctors and dtors, and will throw on demand during copy. +// +// 5) gnu_char, gnu_char_traits, abstract character classes and +// char_traits specializations for testing instantiations. #ifndef _GLIBCPP_TESTSUITE_HOOKS_H #define _GLIBCPP_TESTSUITE_HOOKS_H +#include +#include + #ifdef DEBUG_ASSERT # include # define VERIFY(fn) assert(fn) @@ -61,8 +67,6 @@ # define VERIFY(fn) test &= (fn) #endif -#include - // Defined in GLIBCPP_CONFIGURE_TESTSUITE. #ifndef _GLIBCPP_MEM_LIMITS // Don't do memory limits. @@ -146,6 +150,80 @@ class gnu_copy_tracker static int itsDtorCount; }; +struct gnu_char +{ + unsigned long c; +}; + +struct gnu_int +{ + unsigned long i; +}; + +struct gnu_state +{ + unsigned long l; + unsigned long l2; +}; + +// char_traits specialization +namespace std +{ + template + struct char_traits; + + template<> + struct char_traits + { + typedef gnu_char char_type; + typedef gnu_int int_type; + typedef long pos_type; + typedef unsigned long off_type; + typedef gnu_state state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n); + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c); + + static int_type + to_int_type(const char_type& __c); + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof(); + + static int_type + not_eof(const int_type& __c); + }; +} // namespace std #endif // _GLIBCPP_TESTSUITE_HOOKS_H