Commit f13a69ec by Benjamin Kosnik Committed by Benjamin Kosnik

char_traits.h: Remove generic definitions.


2002-07-30  Benjamin Kosnik  <bkoz@redhat.com>
            Gabriel Dos Reis  <gdr@nerim.net>

	* 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.

Co-Authored-By: Gabriel Dos Reis <gdr@nerim.net>

From-SVN: r55893
parent 506a61b1
2002-07-30 Benjamin Kosnik <bkoz@redhat.com>
Gabriel Dos Reis <gdr@nerim.net>
* 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 <amodra@bigpond.net.au> 2002-07-29 Alan Modra <amodra@bigpond.net.au>
* config/cpu/powerpc/cpu_limits.h (__glibcpp_long_bits): Define. * config/cpu/powerpc/cpu_limits.h (__glibcpp_long_bits): Define.
......
// Character Traits for use by standard string and iostream -*- C++ -*- // 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 // 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 // software; you can redistribute it and/or modify it under the
...@@ -57,82 +58,53 @@ namespace std ...@@ -57,82 +58,53 @@ namespace std
struct char_traits struct char_traits
{ {
typedef _CharT char_type; typedef _CharT char_type;
// Unsigned as wint_t in unsigned. // Unsigned as wint_t is unsigned.
typedef unsigned long int_type; typedef unsigned long int_type;
typedef streampos pos_type; typedef streampos pos_type;
typedef streamoff off_type; typedef streamoff off_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
static void static void
assign(char_type& __c1, const char_type& __c2) assign(char_type& __c1, const char_type& __c2);
{ __c1 = __c2; }
static bool static bool
eq(const char_type& __c1, const char_type& __c2) eq(const char_type& __c1, const char_type& __c2);
{ return __c1 == __c2; }
static bool static bool
lt(const char_type& __c1, const char_type& __c2) lt(const char_type& __c1, const char_type& __c2);
{ return __c1 < __c2; }
static int static int
compare(const char_type* __s1, const char_type* __s2, size_t __n) 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 static size_t
length(const char_type* __s) length(const char_type* __s);
{
const char_type* __p = __s;
while (*__p) ++__p;
return (__p - __s);
}
static const char_type* static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a) 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* static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n) move(char_type* __s1, const char_type* __s2, size_t __n);
{ return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); }
static char_type* static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n) copy(char_type* __s1, const char_type* __s2, size_t __n);
{ return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); }
static char_type* static char_type*
assign(char_type* __s, size_t __n, char_type __a) 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 static char_type
to_char_type(const int_type& __c) to_char_type(const int_type& __c);
{ return char_type(__c); }
static int_type static int_type
to_int_type(const char_type& __c) { return int_type(__c); } to_int_type(const char_type& __c);
static bool static bool
eq_int_type(const int_type& __c1, const int_type& __c2) eq_int_type(const int_type& __c1, const int_type& __c2);
{ return __c1 == __c2; }
static int_type static int_type
eof() { return static_cast<int_type>(-1); } eof();
static int_type static int_type
not_eof(const int_type& __c) not_eof(const int_type& __c);
{ return eq_int_type(__c, eof()) ? int_type(0) : __c; }
}; };
......
...@@ -105,7 +105,7 @@ namespace std ...@@ -105,7 +105,7 @@ namespace std
bool bool
operator!=(const fpos& __pos) const operator!=(const fpos& __pos) const
{ return _M_off != __pos._M_off; } { return _M_off != __pos._M_off; }
streamoff streamoff
_M_position() const { return _M_off; } _M_position() const { return _M_off; }
......
...@@ -112,7 +112,8 @@ namespace std ...@@ -112,7 +112,8 @@ namespace std
{ {
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
bool __testput = _M_out_cur && _M_out_beg < _M_out_end; 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; return __ret;
// NB: Do this here so that re-opened filebufs will be cool... // NB: Do this here so that re-opened filebufs will be cool...
...@@ -155,96 +156,6 @@ namespace std ...@@ -155,96 +156,6 @@ namespace std
_M_last_overflowed = false; _M_last_overflowed = false;
return __ret; return __ret;
} }
template<typename _CharT, typename _Traits>
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<char*>(_M_in_beg),
_M_buf_size);
__ilen = __elen;
}
else
{
char* __buf = static_cast<char*>(__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 _CharT, typename _Traits> template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type typename basic_filebuf<_CharT, _Traits>::int_type
......
...@@ -54,13 +54,14 @@ namespace std ...@@ -54,13 +54,14 @@ namespace std
__int_type __c = __sb->sgetc(); __int_type __c = __sb->sgetc();
if (__in._M_check_facet(__in._M_fctype)) if (__in._M_check_facet(__in._M_fctype))
while (__c != __eof while (!traits_type::eq_int_type(__c, __eof)
&& __in._M_fctype->is(ctype_base::space, __c)) && __in._M_fctype->is(ctype_base::space,
traits_type::to_char_type(__c)))
__c = __sb->snextc(); __c = __sb->snextc();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//195. Should basic_istream::sentry's constructor ever set eofbit? //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); __in.setstate(ios_base::eofbit);
#endif #endif
} }
...@@ -521,7 +522,7 @@ namespace std ...@@ -521,7 +522,7 @@ namespace std
{ {
__c = this->rdbuf()->sbumpc(); __c = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3 // 27.6.1.1 paragraph 3
if (__c != __eof) if (!traits_type::eq_int_type(__c, __eof))
_M_gcount = 1; _M_gcount = 1;
else else
this->setstate(ios_base::eofbit | ios_base::failbit); this->setstate(ios_base::eofbit | ios_base::failbit);
...@@ -552,7 +553,7 @@ namespace std ...@@ -552,7 +553,7 @@ namespace std
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
int_type __bufval = this->rdbuf()->sbumpc(); int_type __bufval = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3 // 27.6.1.1 paragraph 3
if (__bufval != __eof) if (!traits_type::eq_int_type(__bufval, __eof))
{ {
_M_gcount = 1; _M_gcount = 1;
__c = traits_type::to_char_type(__bufval); __c = traits_type::to_char_type(__bufval);
...@@ -588,13 +589,15 @@ namespace std ...@@ -588,13 +589,15 @@ namespace std
__streambuf_type* __sb = this->rdbuf(); __streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc(); 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); *__s++ = traits_type::to_char_type(__c);
__c = __sb->snextc(); __c = __sb->snextc();
++_M_gcount; ++_M_gcount;
} }
if (__c == __eof) if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit); this->setstate(ios_base::eofbit);
} }
catch(exception& __fail) catch(exception& __fail)
...@@ -627,14 +630,17 @@ namespace std ...@@ -627,14 +630,17 @@ namespace std
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
__streambuf_type* __this_sb = this->rdbuf(); __streambuf_type* __this_sb = this->rdbuf();
int_type __c = __this_sb->sgetc(); int_type __c = __this_sb->sgetc();
char_type __c2 = traits_type::to_char_type(__c);
while (__c != __eof && __c != __idelim while (!traits_type::eq_int_type(__c, __eof)
&& (__sb.sputc(traits_type::to_char_type(__c)) != __eof)) && !traits_type::eq_int_type(__c, __idelim)
&& !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
{ {
++_M_gcount; ++_M_gcount;
__c = __this_sb->snextc(); __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); this->setstate(ios_base::eofbit);
} }
catch(exception& __fail) catch(exception& __fail)
...@@ -667,17 +673,19 @@ namespace std ...@@ -667,17 +673,19 @@ namespace std
__streambuf_type* __sb = this->rdbuf(); __streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc(); 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); *__s++ = traits_type::to_char_type(__c);
__c = __sb->snextc(); __c = __sb->snextc();
++_M_gcount; ++_M_gcount;
} }
if (__c == __eof) if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit); this->setstate(ios_base::eofbit);
else else
{ {
if (__c == __idelim) if (traits_type::eq_int_type(__c, __idelim))
{ {
__sb->sbumpc(); __sb->sbumpc();
++_M_gcount; ++_M_gcount;
...@@ -717,14 +725,16 @@ namespace std ...@@ -717,14 +725,16 @@ namespace std
int_type __c = __sb->sgetc(); int_type __c = __sb->sgetc();
__n = min(__n, numeric_limits<streamsize>::max()); __n = min(__n, numeric_limits<streamsize>::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(); __c = __sb->snextc();
++_M_gcount; ++_M_gcount;
} }
if (__c == __eof) if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit); this->setstate(ios_base::eofbit);
else if (__c == __delim) else if (traits_type::eq_int_type(__c, __delim))
{ {
__sb->sbumpc(); __sb->sbumpc();
++_M_gcount; ++_M_gcount;
...@@ -806,9 +816,8 @@ namespace std ...@@ -806,9 +816,8 @@ namespace std
{ {
try try
{ {
const int_type __eof = traits_type::eof();
streamsize __num = this->rdbuf()->in_avail(); streamsize __num = this->rdbuf()->in_avail();
if (__num != static_cast<streamsize>(__eof)) if (__num > 0)
{ {
__num = min(__num, __n); __num = min(__num, __n);
if (__num) if (__num)
...@@ -843,7 +852,8 @@ namespace std ...@@ -843,7 +852,8 @@ namespace std
{ {
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf(); __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); this->setstate(ios_base::badbit);
} }
catch(exception& __fail) catch(exception& __fail)
...@@ -873,7 +883,8 @@ namespace std ...@@ -873,7 +883,8 @@ namespace std
{ {
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf(); __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); this->setstate(ios_base::badbit);
} }
catch(exception& __fail) catch(exception& __fail)
...@@ -895,7 +906,7 @@ namespace std ...@@ -895,7 +906,7 @@ namespace std
basic_istream<_CharT, _Traits>:: basic_istream<_CharT, _Traits>::
sync(void) sync(void)
{ {
int __ret = traits_type::eof(); int __ret = -1;
_M_gcount = 0; _M_gcount = 0;
sentry __cerb(*this, true); sentry __cerb(*this, true);
if (__cerb) if (__cerb)
...@@ -903,10 +914,13 @@ namespace std ...@@ -903,10 +914,13 @@ namespace std
try try
{ {
__streambuf_type* __sb = this->rdbuf(); __streambuf_type* __sb = this->rdbuf();
if (!__sb || __ret == __sb->pubsync()) if (__sb)
this->setstate(ios_base::badbit); {
else if (__sb->pubsync() == -1)
__ret = 0; this->setstate(ios_base::badbit);
else
__ret = 0;
}
} }
catch(exception& __fail) catch(exception& __fail)
{ {
...@@ -1186,16 +1200,18 @@ namespace std ...@@ -1186,16 +1200,18 @@ namespace std
__streambuf_type* __sb = __in.rdbuf(); __streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sbumpc(); __int_type __c = __sb->sbumpc();
const __int_type __eof = _Traits::eof(); 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); __str += _Traits::to_char_type(__c);
++__extracted; ++__extracted;
__c = __sb->sbumpc(); __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); __in.setstate(ios_base::eofbit);
} }
if (!__extracted && !__testdelim) if (!__extracted && !__testdelim)
......
...@@ -55,6 +55,9 @@ namespace std ...@@ -55,6 +55,9 @@ namespace std
# define _GLIBCPP_NUM_FACETS 14 # define _GLIBCPP_NUM_FACETS 14
#endif #endif
template<typename _CharT, typename _Traits>
struct __pad;
// 22.2.1.1 Template class ctype // 22.2.1.1 Template class ctype
// Include host and configuration specific ctype enums for ctype_base. // Include host and configuration specific ctype enums for ctype_base.
#include <bits/ctype_base.h> #include <bits/ctype_base.h>
...@@ -652,6 +655,7 @@ namespace std ...@@ -652,6 +655,7 @@ namespace std
virtual iter_type virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
virtual iter_type virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
...@@ -697,6 +701,23 @@ namespace std ...@@ -697,6 +701,23 @@ namespace std
template<typename _CharT, typename _InIter> template<typename _CharT, typename _InIter>
locale::id num_get<_CharT, _InIter>::id; locale::id num_get<_CharT, _InIter>::id;
#if 0
// Partial specialization for istreambuf_iterator, so can use traits_type.
template<typename _CharT>
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<typename _CharT, typename _OutIter> template<typename _CharT, typename _OutIter>
class num_put : public locale::facet, public __num_base class num_put : public locale::facet, public __num_base
{ {
......
...@@ -474,7 +474,8 @@ namespace std ...@@ -474,7 +474,8 @@ namespace std
streamsize __len = 1; streamsize __len = 1;
if (__w > __len) 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; __len = __w;
} }
__out.write(__pads, __len); __out.write(__pads, __len);
...@@ -509,7 +510,8 @@ namespace std ...@@ -509,7 +510,8 @@ namespace std
streamsize __len = 1; streamsize __len = 1;
if (__w > __len) if (__w > __len)
{ {
__pad(__out, __out.fill(), __pads, &__c, __w, __len, false); __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads,
&__c, __w, __len, false);
__len = __w; __len = __w;
} }
__out.write(__pads, __len); __out.write(__pads, __len);
...@@ -542,7 +544,8 @@ namespace std ...@@ -542,7 +544,8 @@ namespace std
streamsize __len = static_cast<streamsize>(_Traits::length(__s)); streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len) 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; __s = __pads;
__len = __w; __len = __w;
} }
...@@ -590,7 +593,8 @@ namespace std ...@@ -590,7 +593,8 @@ namespace std
if (__w > __len) 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; __str = __pads;
__len = __w; __len = __w;
} }
...@@ -628,7 +632,8 @@ namespace std ...@@ -628,7 +632,8 @@ namespace std
if (__w > __len) if (__w > __len)
{ {
__pad(__out, __out.fill(), __pads, __s, __w, __len, false); __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads,
__s, __w, __len, false);
__s = __pads; __s = __pads;
__len = __w; __len = __w;
} }
...@@ -668,7 +673,8 @@ namespace std ...@@ -668,7 +673,8 @@ namespace std
#endif #endif
if (__w > __len) 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; __s = __pads;
__len = __w; __len = __w;
} }
......
...@@ -184,7 +184,7 @@ namespace std ...@@ -184,7 +184,7 @@ namespace std
if (_M_buf_size) 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* __beg = NULL;
char_type* __end = NULL; char_type* __end = NULL;
bool __testin = (ios_base::in & _M_mode & __mode) != 0; bool __testin = (ios_base::in & _M_mode & __mode) != 0;
......
...@@ -69,13 +69,13 @@ namespace std ...@@ -69,13 +69,13 @@ namespace std
public: public:
istreambuf_iterator() throw() istreambuf_iterator() throw()
: _M_sbuf(0), _M_c(-2) { } : _M_sbuf(0), _M_c(traits_type::eof()) { }
istreambuf_iterator(istream_type& __s) throw() 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() 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. // NB: The result of operator*() on an end of stream is undefined.
char_type char_type
...@@ -85,21 +85,25 @@ namespace std ...@@ -85,21 +85,25 @@ namespace std
istreambuf_iterator& istreambuf_iterator&
operator++() 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; _M_sbuf = 0;
else else
_M_c = -2; _M_c = __eof;
return *this; return *this;
} }
istreambuf_iterator istreambuf_iterator
operator++(int) operator++(int)
{ {
const int_type __eof = traits_type::eof();
istreambuf_iterator __old = *this; 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; _M_sbuf = 0;
else else
_M_c = -2; _M_c = __eof;
return __old; return __old;
} }
...@@ -110,8 +114,8 @@ namespace std ...@@ -110,8 +114,8 @@ namespace std
equal(const istreambuf_iterator& __b) const equal(const istreambuf_iterator& __b) const
{ {
const int_type __eof = traits_type::eof(); const int_type __eof = traits_type::eof();
bool __thiseof = _M_get() == __eof; bool __thiseof = traits_type::eq_int_type(_M_get(), __eof);
bool __beof = __b._M_get() == __eof; bool __beof = traits_type::eq_int_type(__b._M_get(), __eof);
return (__thiseof && __beof || (!__thiseof && !__beof)); return (__thiseof && __beof || (!__thiseof && !__beof));
} }
#endif #endif
...@@ -120,13 +124,14 @@ namespace std ...@@ -120,13 +124,14 @@ namespace std
int_type int_type
_M_get() const _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_sbuf)
{ {
if (_M_c != static_cast<int_type>(-2)) if (!traits_type::eq_int_type(_M_c, __eof))
__ret = _M_c; __ret = _M_c;
else else
if ((__ret = _M_sbuf->sgetc()) == traits_type::eof()) if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof))
_M_sbuf = 0; _M_sbuf = 0;
} }
return __ret; return __ret;
......
...@@ -286,7 +286,16 @@ namespace std ...@@ -286,7 +286,16 @@ namespace std
} }
}; };
// Explicit specializations.
template<>
basic_filebuf<char>::int_type
basic_filebuf<char>::_M_underflow_common(bool __bump);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
basic_filebuf<wchar_t>::int_type
basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
#endif
// 27.8.1.5 Template class basic_ifstream // 27.8.1.5 Template class basic_ifstream
/** /**
......
...@@ -71,6 +71,7 @@ namespace std ...@@ -71,6 +71,7 @@ namespace std
// Non-standard Types: // Non-standard Types:
typedef ctype<char_type> __ctype_type; typedef ctype<char_type> __ctype_type;
typedef basic_streambuf<char_type, traits_type> __streambuf_type; typedef basic_streambuf<char_type, traits_type> __streambuf_type;
typedef typename traits_type::state_type __state_type;
friend class basic_ios<char_type, traits_type>; friend class basic_ios<char_type, traits_type>;
friend class basic_istream<char_type, traits_type>; friend class basic_istream<char_type, traits_type>;
...@@ -132,6 +133,9 @@ namespace std ...@@ -132,6 +133,9 @@ namespace std
char_type* _M_pback_end_save; char_type* _M_pback_end_save;
bool _M_pback_init; bool _M_pback_init;
// Yet unused.
fpos<__state_type> _M_pos;
// Initializes pback buffers, and moves normal buffers to safety. // Initializes pback buffers, and moves normal buffers to safety.
// Assumptions: // Assumptions:
// _M_in_cur has already been moved back // _M_in_cur has already been moved back
......
...@@ -70,6 +70,7 @@ sources = \ ...@@ -70,6 +70,7 @@ sources = \
concept-inst.cc \ concept-inst.cc \
ctype.cc \ ctype.cc \
ext-inst.cc \ ext-inst.cc \
fstream.cc \
fstream-inst.cc \ fstream-inst.cc \
functexcept.cc \ functexcept.cc \
globals.cc \ globals.cc \
......
...@@ -175,6 +175,7 @@ sources = \ ...@@ -175,6 +175,7 @@ sources = \
concept-inst.cc \ concept-inst.cc \
ctype.cc \ ctype.cc \
ext-inst.cc \ ext-inst.cc \
fstream.cc \
fstream-inst.cc \ fstream-inst.cc \
functexcept.cc \ functexcept.cc \
globals.cc \ globals.cc \
...@@ -279,7 +280,7 @@ LDFLAGS = @LDFLAGS@ ...@@ -279,7 +280,7 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
libstdc___la_OBJECTS = basic_file.lo bitset.lo c++locale.lo codecvt.lo \ 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 \ 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 \ istream-inst.lo limits.lo locale-inst.lo locale.lo localename.lo \
messages.lo misc-inst.lo monetary.lo numeric.lo ostream-inst.lo \ messages.lo misc-inst.lo monetary.lo numeric.lo ostream-inst.lo \
sstream-inst.lo stdexcept.lo stl-inst.lo streambuf-inst.lo \ sstream-inst.lo stdexcept.lo stl-inst.lo streambuf-inst.lo \
......
...@@ -420,15 +420,7 @@ namespace std ...@@ -420,15 +420,7 @@ namespace std
bool bool
__verify_grouping<char>(const basic_string<char>&, basic_string<char>&); __verify_grouping<char>(const basic_string<char>&, basic_string<char>&);
template template class __pad<char, char_traits<char> >;
void
__pad<char>(ios_base&, char, char*, const char *, streamsize,
streamsize, const bool);
template
void
__pad<char, char_traits<char> >(ios_base&, char, char*, const char *,
streamsize, streamsize, const bool);
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template template
...@@ -440,29 +432,23 @@ namespace std ...@@ -440,29 +432,23 @@ namespace std
__verify_grouping<wchar_t>(const basic_string<wchar_t>&, __verify_grouping<wchar_t>(const basic_string<wchar_t>&,
basic_string<wchar_t>&); basic_string<wchar_t>&);
template template class __pad<wchar_t, char_traits<wchar_t> >;
void #endif
__pad<wchar_t>(ios_base&, wchar_t, wchar_t*, const wchar_t*,
streamsize, streamsize, const bool);
template
void
__pad<wchar_t, char_traits<wchar_t> >(ios_base&, wchar_t, wchar_t*,
const wchar_t*, streamsize,
streamsize, const bool);
#endif // _GLIBCPP_USE_WCHAR_T
template template
int 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 template
int 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 template
int 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 template
int int
...@@ -471,7 +457,8 @@ namespace std ...@@ -471,7 +457,8 @@ namespace std
template template
int 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 template
int int
......
...@@ -36,6 +36,93 @@ template<typename T> ...@@ -36,6 +36,93 @@ template<typename T>
struct B { }; struct B { };
// char_traits specialization
namespace std
{
template<>
struct char_traits<A<B> >
{
typedef A<B> 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<int_type>(-1); }
static int_type
not_eof(const int_type& __c)
{ return eq_int_type(__c, eof()) ? int_type(0) : __c; }
};
} // namespace std
void test01() void test01()
{ {
// 1 POD types : resize, capacity, reserve // 1 POD types : resize, capacity, reserve
......
...@@ -23,10 +23,71 @@ ...@@ -23,10 +23,71 @@
#include <locale> #include <locale>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
using namespace std;
#ifdef _GLIBCPP_USE___ENC_TRAITS #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<unicode_t>
{
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<char_type*>(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? > how do I check that these conversions are correct?
Very easy. Since all the characters are from ASCII you simply 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). ...@@ -51,7 +112,7 @@ it shows that the other byte-order is used (25856 == 0x6500).
void void
initialize_state(__enc_traits& state) initialize_state(std::__enc_traits& state)
{ state._M_init(); } { state._M_init(); }
// Partial specialization using __enc_traits. // Partial specialization using __enc_traits.
...@@ -59,8 +120,8 @@ initialize_state(__enc_traits& state) ...@@ -59,8 +120,8 @@ initialize_state(__enc_traits& state)
// UNICODE - UCS2 (big endian) // UNICODE - UCS2 (big endian)
void test01() void test01()
{ {
using namespace std;
typedef codecvt_base::result result; typedef codecvt_base::result result;
typedef unsigned short unicode_t;
typedef unicode_t int_type; typedef unicode_t int_type;
typedef char ext_type; typedef char ext_type;
typedef __enc_traits enc_type; typedef __enc_traits enc_type;
...@@ -146,6 +207,7 @@ void test01() ...@@ -146,6 +207,7 @@ void test01()
// UNICODE - UCS2 (little endian) // UNICODE - UCS2 (little endian)
void test02() void test02()
{ {
using namespace std;
typedef codecvt_base::result result; typedef codecvt_base::result result;
typedef unsigned short unicode_t; typedef unsigned short unicode_t;
typedef unicode_t int_type; typedef unicode_t int_type;
......
// 2000-08-23 Benjamin Kosnik <bkoz@cygnus.com> // 2000-08-23 Benjamin Kosnik <bkoz@cygnus.com>
// 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 // 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 // software; you can redistribute it and/or modify it under the
...@@ -23,21 +23,80 @@ ...@@ -23,21 +23,80 @@
#include <locale> #include <locale>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
using namespace std;
#ifdef _GLIBCPP_USE___ENC_TRAITS #ifdef _GLIBCPP_USE___ENC_TRAITS
#ifdef _GLIBCPP_USE_WCHAR_T #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<unicode_t>
{
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<char_type*>(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 void
initialize_state(__enc_traits& state) initialize_state(std::__enc_traits& state)
{ state._M_init(); } { state._M_init(); }
// Partial specialization using __enc_traits. // Partial specialization using __enc_traits.
// codecvt<unicode_t, wchar_t, __enc_traits> // codecvt<unicode_t, wchar_t, __enc_traits>
void test01() void test01()
{ {
using namespace std;
typedef codecvt_base::result result; typedef codecvt_base::result result;
typedef unsigned short unicode_t;
typedef unicode_t int_type; typedef unicode_t int_type;
typedef wchar_t ext_type; typedef wchar_t ext_type;
typedef __enc_traits enc_type; typedef __enc_traits enc_type;
......
...@@ -48,11 +48,70 @@ public: ...@@ -48,11 +48,70 @@ public:
std::locale::id gnu_facet::id; 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<unicode_t>
{
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<char_type*>(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() void test01()
{ {
using namespace std; using namespace std;
typedef unsigned short unicode_t;
typedef unicode_t int_type; typedef unicode_t int_type;
typedef char ext_type; typedef char ext_type;
typedef __enc_traits enc_type; typedef __enc_traits enc_type;
......
...@@ -42,11 +42,67 @@ void test01() ...@@ -42,11 +42,67 @@ void test01()
// test05 // test05
// libstdc++/1886 // libstdc++/1886
// should be able to instantiate basic_filebuf for non-standard types. // should be able to instantiate basic_filebuf for non-standard types.
template class std::basic_filebuf<short, std::char_traits<short> >; namespace test
{
using namespace std;
typedef short type_t;
template class basic_filebuf<type_t, char_traits<type_t> >;
template class basic_filebuf<gnu_char, char_traits<gnu_char> >;
} // 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_char_type> 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<gnu_char_type>::int_type
std::basic_streambuf<gnu_char_type>::_S_pback_size;
#endif
int main() int main()
{ {
test01(); test01();
test07();
return 0; return 0;
} }
......
...@@ -514,54 +514,6 @@ void test06() ...@@ -514,54 +514,6 @@ void test06()
VERIFY( buffer[0] == 'a' ); 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_char_type> 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<gnu_char_type>::int_type
std::basic_streambuf<gnu_char_type>::_S_pback_size;
#endif
main() main()
{ {
test01(); test01();
...@@ -571,7 +523,6 @@ main() ...@@ -571,7 +523,6 @@ main()
test04(); test04();
test05(); test05();
test06(); test06();
test07();
return 0; return 0;
} }
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing basic_fstream with NO OTHER INCLUDES. // NB: This file is for testing basic_fstream with NO OTHER INCLUDES.
#include <fstream> #include <fstream>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_fstream<type_t, char_traits<type_t> >; template class basic_fstream<type_t, char_traits<type_t> >;
template class basic_fstream<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -34,6 +34,176 @@ ...@@ -34,6 +34,176 @@
#include <iostream> #include <iostream>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
// char_traits specialization
namespace std
{
template<>
struct char_traits<unsigned short>
{
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<int_type>(-1); }
static int_type
not_eof(const int_type& __c)
{ return eq_int_type(__c, eof()) ? int_type(0) : __c; }
};
template<>
struct char_traits<unsigned char>
{
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<int_type>(-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 class gnu_filebuf: public std::filebuf
{ {
int i; int i;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing istream with NO OTHER INCLUDES. // NB: This file is for testing istream with NO OTHER INCLUDES.
#include <istream> #include <istream>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_istream<type_t, char_traits<type_t> >; template class basic_istream<type_t, char_traits<type_t> >;
template class basic_istream<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing ostream with NO OTHER INCLUDES. // NB: This file is for testing ostream with NO OTHER INCLUDES.
#include <ostream> #include <ostream>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_ostream<type_t, char_traits<type_t> >; template class basic_ostream<type_t, char_traits<type_t> >;
template class basic_ostream<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing basic_streambuf with NO OTHER INCLUDES. // NB: This file is for testing basic_streambuf with NO OTHER INCLUDES.
#include <streambuf> #include <streambuf>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_streambuf<type_t, char_traits<type_t> >; template class basic_streambuf<type_t, char_traits<type_t> >;
template class basic_streambuf<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES. // NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES.
#include <sstream> #include <sstream>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_stringbuf<type_t, char_traits<type_t> >; template class basic_stringbuf<type_t, char_traits<type_t> >;
template class basic_stringbuf<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
// NB: This file is for testing basic_stringstream with NO OTHER INCLUDES. // NB: This file is for testing basic_stringstream with NO OTHER INCLUDES.
#include <sstream> #include <sstream>
#include <testsuite_hooks.h>
// { dg-do compile } // { dg-do compile }
...@@ -51,6 +52,7 @@ namespace test ...@@ -51,6 +52,7 @@ namespace test
using namespace std; using namespace std;
typedef short type_t; typedef short type_t;
template class basic_stringstream<type_t, char_traits<type_t> >; template class basic_stringstream<type_t, char_traits<type_t> >;
template class basic_stringstream<gnu_char, char_traits<gnu_char> >;
} // test } // test
int main() int main()
......
...@@ -50,10 +50,16 @@ ...@@ -50,10 +50,16 @@
// 4) gnu_copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>. // 4) gnu_copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>.
// A class with nontrivial ctor/dtor that provides the ability to track the // 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. // 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 #ifndef _GLIBCPP_TESTSUITE_HOOKS_H
#define _GLIBCPP_TESTSUITE_HOOKS_H #define _GLIBCPP_TESTSUITE_HOOKS_H
#include <bits/c++config.h>
#include <cstddef>
#ifdef DEBUG_ASSERT #ifdef DEBUG_ASSERT
# include <cassert> # include <cassert>
# define VERIFY(fn) assert(fn) # define VERIFY(fn) assert(fn)
...@@ -61,8 +67,6 @@ ...@@ -61,8 +67,6 @@
# define VERIFY(fn) test &= (fn) # define VERIFY(fn) test &= (fn)
#endif #endif
#include <bits/c++config.h>
// Defined in GLIBCPP_CONFIGURE_TESTSUITE. // Defined in GLIBCPP_CONFIGURE_TESTSUITE.
#ifndef _GLIBCPP_MEM_LIMITS #ifndef _GLIBCPP_MEM_LIMITS
// Don't do memory limits. // Don't do memory limits.
...@@ -146,6 +150,80 @@ class gnu_copy_tracker ...@@ -146,6 +150,80 @@ class gnu_copy_tracker
static int itsDtorCount; 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<class _CharT>
struct char_traits;
template<>
struct char_traits<gnu_char>
{
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 #endif // _GLIBCPP_TESTSUITE_HOOKS_H
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