summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog29
-rw-r--r--libstdc++-v3/include/bits/basic_ios.h18
-rw-r--r--libstdc++-v3/include/bits/basic_ios.tcc20
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc88
-rw-r--r--libstdc++-v3/include/bits/istream.tcc47
-rw-r--r--libstdc++-v3/include/bits/locale_classes.h10
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc16
-rw-r--r--libstdc++-v3/include/bits/localefwd.h13
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc94
-rw-r--r--libstdc++-v3/include/std/std_fstream.h4
-rw-r--r--libstdc++-v3/include/std/std_streambuf.h11
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc54
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc55
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/1.cc45
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc54
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc55
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/9322.cc53
17 files changed, 494 insertions, 172 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9ea0c9f2a29..c7273a27e39 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,32 @@
+2003-05-12 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/std/std_fstream.h (basic_filebuf::_M_codecvt): Add
+ cached member.
+ * include/bits/fstream.tcc (basic_filebuf::basic_filebuf):
+ Initialize _M_codecvt.
+ (basic_filebuf::imbue): Same.
+ (basic_filebuf::showmanyc): Use it.
+ (basic_filebuf::underflow): Use it.
+ (basic_filebuf::_M_convert_to_external): Use it.
+ (basic_filebuf::seekoff): Use it.
+ (basic_filebuf::imbue): Use it, tweaks.
+ * include/bits/localefwd.h (__check_facet): New.
+ * include/bits/locale_classes.h: Tweaks.
+ * include/bits/locale_facets.tcc: Tweaks.
+ * include/bits/basic_ios.h (basic_ios::_M_check_facet): Remove.
+ _M_fctype to _M_ctype, _M_fnumput to _M_num_put, _M_fnumget to
+ _M_num_get. Change _M_check_facet to __check_facet. Tweaks.
+ * include/bits/basic_ios.tcc: Same.
+ * include/bits/istream.tcc: Same.
+ * include/bits/ostream.tcc: Same.
+ * include/std/std_streambuf.h: Same.
+ * testsuite/27_io/basic_filebuf/imbue/char/2.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/char/3.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/1.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/9322.cc: New.
+
2003-05-12 Paolo Carlini <pcarlini@unitus.it>
* testsuite/27_io/basic_filebuf/sgetc/char/1.cc: Remove
diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h
index 5be11a2590d..98b73cadd7c 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -90,11 +90,11 @@ namespace std
basic_streambuf<_CharT, _Traits>* _M_streambuf;
// Cached use_facet<ctype>, which is based on the current locale info.
- const __ctype_type* _M_fctype;
+ const __ctype_type* _M_ctype;
// For ostream.
- const __numput_type* _M_fnumput;
+ const __numput_type* _M_num_put;
// For istream.
- const __numget_type* _M_fnumget;
+ const __numget_type* _M_num_get;
public:
//@{
@@ -241,7 +241,7 @@ namespace std
*/
explicit
basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
- : ios_base(), _M_fctype(0), _M_fnumput(0), _M_fnumget(0)
+ : ios_base(), _M_ctype(0), _M_num_put(0), _M_num_get(0)
{ this->init(__sb); }
/**
@@ -419,7 +419,7 @@ namespace std
* The default constructor does nothing and is not normally
* accessible to users.
*/
- basic_ios() : ios_base(), _M_fctype(0), _M_fnumput(0), _M_fnumget(0)
+ basic_ios() : ios_base(), _M_ctype(0), _M_num_put(0), _M_num_get(0)
{ }
/**
@@ -431,14 +431,6 @@ namespace std
void
init(basic_streambuf<_CharT, _Traits>* __sb);
- bool
- _M_check_facet(const locale::facet* __f) const
- {
- if (!__f)
- __throw_bad_cast();
- return true;
- }
-
void
_M_cache_locale(const locale& __loc);
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc
index 0c1e7357098..cf2701effb2 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -110,22 +110,12 @@ namespace std
template<typename _CharT, typename _Traits>
char
basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const
- {
- char __ret = __dfault;
- if (_M_check_facet(_M_fctype))
- __ret = _M_fctype->narrow(__c, __dfault);
- return __ret;
- }
+ { return __check_facet(_M_ctype).narrow(__c, __dfault); }
template<typename _CharT, typename _Traits>
_CharT
basic_ios<_CharT, _Traits>::widen(char __c) const
- {
- char_type __ret = char_type();
- if (_M_check_facet(_M_fctype))
- __ret = _M_fctype->widen(__c);
- return __ret;
- }
+ { return __check_facet(_M_ctype).widen(__c); }
// Locales:
template<typename _CharT, typename _Traits>
@@ -181,11 +171,11 @@ namespace std
basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc)
{
if (__builtin_expect(has_facet<__ctype_type>(__loc), true))
- _M_fctype = &use_facet<__ctype_type>(__loc);
+ _M_ctype = &use_facet<__ctype_type>(__loc);
if (__builtin_expect(has_facet<__numput_type>(__loc), true))
- _M_fnumput = &use_facet<__numput_type>(__loc);
+ _M_num_put = &use_facet<__numput_type>(__loc);
if (__builtin_expect(has_facet<__numget_type>(__loc), true))
- _M_fnumget = &use_facet<__numget_type>(__loc);
+ _M_num_get = &use_facet<__numget_type>(__loc);
static_cast<__locale_cache<_CharT>&>(_M_cache())._M_init(__loc);
}
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 40d1ece324a..3397071bd84 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -78,8 +78,13 @@ namespace std
_M_state_cur(__state_type()), _M_state_beg(__state_type()),
_M_buf(NULL), _M_buf_size(BUFSIZ), _M_buf_allocated(false),
_M_last_overflowed(false), _M_pback_cur_save(0),
- _M_pback_end_save(0), _M_pback_init(false)
- { this->_M_buf_unified = true; }
+ _M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0)
+ {
+ this->_M_buf_unified = true;
+ if (__builtin_expect(has_facet<__codecvt_type>(this->_M_buf_locale),
+ true))
+ _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
+ }
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
@@ -163,17 +168,14 @@ namespace std
{
streamsize __ret = -1;
const bool __testin = this->_M_mode & ios_base::in;
- const locale __loc = this->getloc();
- const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
if (__testin && this->is_open())
{
- __ret = this->_M_in_end - this->_M_in_cur;
-
// For a stateful encoding (-1) the pending sequence might be just
// shift and unshift prefixes with no actual character.
- if (__cvt.encoding() >= 0)
- __ret += _M_file.showmanyc() / __cvt.max_length();
+ __ret = this->_M_in_end - this->_M_in_cur;
+ if (__check_facet(_M_codecvt).encoding() >= 0)
+ __ret += _M_file.showmanyc() / _M_codecvt->max_length();
}
_M_last_overflowed = false;
@@ -220,9 +222,8 @@ namespace std
{
streamsize __elen = 0;
streamsize __ilen = 0;
- const locale __loc = this->getloc();
- const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
- if (__cvt.always_noconv())
+
+ if (__check_facet(_M_codecvt).always_noconv())
{
__elen = _M_file.xsgetn(reinterpret_cast<char*>(this->_M_in_beg), _M_buf_size);
__ilen = __elen;
@@ -235,9 +236,9 @@ namespace std
const char* __eend;
char_type* __iend;
codecvt_base::result __r;
- __r = __cvt.in(_M_state_cur, __buf, __buf + __elen, __eend,
- this->_M_in_beg,
- this->_M_in_beg + _M_buf_size, __iend);
+ __r = _M_codecvt->in(_M_state_cur, __buf, __buf + __elen,
+ __eend, this->_M_in_beg,
+ this->_M_in_beg + _M_buf_size, __iend);
if (__r == codecvt_base::ok)
__ilen = __iend - this->_M_in_beg;
else if (__r == codecvt_base::noconv)
@@ -400,7 +401,6 @@ namespace std
else
__ret = this->_M_overflow(__c);
}
-
_M_last_overflowed = false; // Set in _M_overflow, below.
return __ret;
}
@@ -414,9 +414,7 @@ namespace std
streamsize __elen = 0;
streamsize __plen = 0;
- const locale __loc = this->getloc();
- const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
- if (__cvt.always_noconv() && __ilen)
+ if (__check_facet(_M_codecvt).always_noconv() && __ilen)
{
__elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__plen += __ilen;
@@ -424,7 +422,7 @@ namespace std
else
{
// Worst-case number of external bytes needed.
- int __ext_multiplier = __cvt.encoding();
+ int __ext_multiplier = _M_codecvt->encoding();
if (__ext_multiplier == -1 || __ext_multiplier == 0)
__ext_multiplier = sizeof(char_type);
streamsize __blen = __ilen * __ext_multiplier;
@@ -432,8 +430,8 @@ namespace std
char* __bend;
const char_type* __iend;
codecvt_base::result __r;
- __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
- __iend, __buf, __buf + __blen, __bend);
+ __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
+ __iend, __buf, __buf + __blen, __bend);
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
__blen = __bend - __buf;
@@ -460,8 +458,9 @@ namespace std
{
const char_type* __iresume = __iend;
streamsize __rlen = this->_M_out_lim - __iend;
- __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
- __iend, __buf, __buf + __blen, __bend);
+ __r = _M_codecvt->out(_M_state_cur, __iresume,
+ __iresume + __rlen, __iend, __buf,
+ __buf + __blen, __bend);
if (__r != codecvt_base::error)
{
__rlen = __bend - __buf;
@@ -470,7 +469,6 @@ namespace std
}
}
}
-
return __elen && __elen == __plen;
}
@@ -510,8 +508,8 @@ namespace std
const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
int __width = 0;
- if (has_facet<__codecvt_type>(this->_M_buf_locale))
- __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
+ if (_M_codecvt)
+ __width = _M_codecvt->encoding();
if (__width < 0)
__width = 0;
@@ -523,20 +521,19 @@ namespace std
if (__way != ios_base::cur || __off != 0)
{
- off_type __computed_off = __width * __off;
-
+ // Sync the internal and external streams.
const bool __testget = this->_M_in_beg < this->_M_in_end;
const bool __testput = this->_M_out_beg < this->_M_out_lim;
- // Sync the internal and external streams.
- // out
+ off_type __computed_off = __width * __off;
+
if (__testput || _M_last_overflowed)
{
// Part one: update the output sequence.
this->sync();
+
// Part two: output unshift sequence.
_M_output_unshift();
}
- //in
else if (__testget && __way == ios_base::cur)
__computed_off += this->_M_in_cur - _M_filepos;
@@ -544,10 +541,10 @@ namespace std
__ret = _M_file.seekoff(__computed_off, __way, __mode);
_M_set_indeterminate();
}
- // NB: Need to do this in case _M_file in indeterminate
- // state, ie _M_file._offset == -1
else
{
+ // NB: Need to do this in case _M_file in indeterminate
+ // state, ie _M_file._offset == -1
pos_type __tmp = _M_file.seekoff(__off, ios_base::cur, __mode);
if (__tmp >= 0)
{
@@ -584,16 +581,23 @@ namespace std
basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc)
{
- const bool __testbeg = this->_M_in_cur == this->_M_in_beg
- && this->_M_out_cur == this->_M_out_beg;
+ const bool __testbeg = !this->seekoff(0, ios_base::cur, this->_M_mode);
+ const bool __teststate = __check_facet(_M_codecvt).encoding() == -1;
- if (__testbeg && this->_M_buf_locale != __loc)
- this->_M_buf_locale = __loc;
-
- // NB this may require the reconversion of previously
- // converted chars. This in turn may cause the reconstruction
- // of the original file. YIKES!!
- // XXX The part in the above comment is not done.
+ if (this->_M_buf_locale != __loc
+ && (!this->is_open() || (__testbeg && !__teststate)))
+ {
+ this->_M_buf_locale = __loc;
+ if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
+ _M_codecvt = &use_facet<__codecvt_type>(__loc);
+
+ // NB This may require the reconversion of previously
+ // converted chars. This in turn may cause the
+ // reconstruction of the original file. YIKES!! This
+ // implementation interprets this requirement as requiring
+ // the file position be at the beginning, and a stateless
+ // encoding, or that the filebuf be closed. Opinions may differ.
+ }
_M_last_overflowed = false;
}
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index cc83f81a923..a9448b09c09 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -53,10 +53,10 @@ namespace std
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sgetc();
- if (__in._M_check_facet(__in._M_fctype))
- while (!traits_type::eq_int_type(__c, __eof)
- && __in._M_fctype->is(ctype_base::space,
- traits_type::to_char_type(__c)))
+ __check_facet(__in._M_ctype);
+ while (!traits_type::eq_int_type(__c, __eof)
+ && __in._M_ctype->is(ctype_base::space,
+ traits_type::to_char_type(__c)))
__c = __sb->snextc();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
@@ -114,8 +114,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -142,8 +141,7 @@ namespace std
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
long __l;
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __l);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __l);
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
if (!(__err & ios_base::failbit)
@@ -178,8 +176,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -206,8 +203,7 @@ namespace std
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
long __l;
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __l);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __l);
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
if (!(__err & ios_base::failbit)
@@ -242,8 +238,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -269,8 +264,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -296,8 +290,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -324,8 +317,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -351,8 +343,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -379,8 +370,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -406,8 +396,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -433,8 +422,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
@@ -460,8 +448,7 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
- if (_M_check_facet(this->_M_fnumget))
- this->_M_fnumget->get(*this, 0, *this, __err, __n);
+ __check_facet(this->_M_num_get).get(*this, 0, *this, __err, __n);
this->setstate(__err);
}
catch(...)
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index 7c447e878f6..e7210f821fe 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -65,13 +65,13 @@ namespace std
friend class _Impl;
template<typename _Facet>
- friend const _Facet&
- use_facet(const locale&);
-
- template<typename _Facet>
friend bool
has_facet(const locale&) throw();
-
+
+ template<typename _Facet>
+ friend const _Facet&
+ use_facet(const locale&);
+
// Category values:
// NB: Order must match _S_facet_categories definition in locale.cc
static const category none = 0;
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 6e09e407104..f44531799f0 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -67,23 +67,23 @@ namespace std
}
template<typename _Facet>
- const _Facet&
- use_facet(const locale& __loc)
+ inline bool
+ has_facet(const locale& __loc) throw()
{
size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
- if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
- __throw_bad_cast();
- return static_cast<const _Facet&>(*__facets[__i]);
+ return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
}
template<typename _Facet>
- bool
- has_facet(const locale& __loc) throw()
+ inline const _Facet&
+ use_facet(const locale& __loc)
{
size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
- return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
+ if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
+ __throw_bad_cast();
+ return static_cast<const _Facet&>(*__facets[__i]);
}
diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h
index ac9e1a95425..16fa8821e9a 100644
--- a/libstdc++-v3/include/bits/localefwd.h
+++ b/libstdc++-v3/include/bits/localefwd.h
@@ -172,12 +172,21 @@ namespace std
class messages_byname;
template<typename _Facet>
+ bool
+ has_facet(const locale& __loc) throw();
+
+ template<typename _Facet>
const _Facet&
use_facet(const locale& __loc);
template<typename _Facet>
- bool
- has_facet(const locale& __loc) throw();
+ inline const _Facet&
+ __check_facet(const _Facet* __f)
+ {
+ if (!__f)
+ __throw_bad_cast();
+ return *__f;
+ }
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index fc7d08a1b6e..620458806a1 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -157,10 +157,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -183,23 +183,19 @@ namespace std
{
try
{
+ bool __b = false;
char_type __c = this->fill();
ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
- if (_M_check_facet(this->_M_fnumput))
+ __check_facet(this->_M_num_put);
+ if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
{
- bool __b = false;
- if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
- {
- unsigned long __l = static_cast<unsigned long>(__n);
- __b = this->_M_fnumput->put(*this, *this,
- __c, __l).failed();
- }
- else
- __b = this->_M_fnumput->put(*this, *this,
- __c, __n).failed();
- if (__b)
- this->setstate(ios_base::badbit);
+ unsigned long __l = static_cast<unsigned long>(__n);
+ __b = this->_M_num_put->put(*this, *this, __c, __l).failed();
}
+ else
+ __b = this->_M_num_put->put(*this, *this, __c, __n).failed();
+ if (__b)
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -222,10 +218,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -249,24 +245,20 @@ namespace std
{
try
{
+ bool __b = false;
char_type __c = this->fill();
ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
- if (_M_check_facet(this->_M_fnumput))
+ __check_facet(this->_M_num_put);
+ if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
{
- bool __b = false;
- if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
- {
- unsigned long long __l;
- __l = static_cast<unsigned long long>(__n);
- __b = this->_M_fnumput->put(*this, *this,
- __c, __l).failed();
- }
- else
- __b = this->_M_fnumput->put(*this, *this,
- __c, __n).failed();
- if (__b)
- this->setstate(ios_base::badbit);
+ unsigned long long __l;
+ __l = static_cast<unsigned long long>(__n);
+ __b = this->_M_num_put->put(*this, *this, __c, __l).failed();
}
+ else
+ __b = this->_M_num_put->put(*this, *this, __c, __n).failed();
+ if (__b)
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -289,10 +281,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -316,10 +308,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -342,10 +334,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
@@ -368,10 +360,10 @@ namespace std
{
try
{
- if (_M_check_facet(this->_M_fnumput))
- if (this->_M_fnumput->put(*this, *this,
- this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __check_facet(this->_M_num_put);
+ if (this->_M_num_put->put(*this, *this, this->fill(),
+ __n).failed())
+ this->setstate(ios_base::badbit);
}
catch(...)
{
diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h
index 0781f0d5294..2ff4ec15d10 100644
--- a/libstdc++-v3/include/std/std_fstream.h
+++ b/libstdc++-v3/include/std/std_fstream.h
@@ -163,6 +163,9 @@ namespace std
bool _M_pback_init;
//@}
+ // Cached codecvt facet.
+ const __codecvt_type* _M_codecvt;
+
// Initializes pback buffers, and moves normal buffers to safety.
// Assumptions:
// _M_in_cur has already been moved back
@@ -403,7 +406,6 @@ namespace std
}
else
_M_file.sync();
-
_M_last_overflowed = false;
return __ret;
}
diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h
index 946e9bc600c..e258501c18b 100644
--- a/libstdc++-v3/include/std/std_streambuf.h
+++ b/libstdc++-v3/include/std/std_streambuf.h
@@ -343,9 +343,10 @@ namespace std
int_type
snextc()
{
- int_type __eof = traits_type::eof();
- return (traits_type::eq_int_type(this->sbumpc(), __eof)
- ? __eof : this->sgetc());
+ int_type __ret = traits_type::eof();
+ if (!traits_type::eq_int_type(this->sbumpc(), __ret))
+ __ret = this->sgetc();
+ return __ret;
}
/**
@@ -699,8 +700,8 @@ namespace std
uflow()
{
int_type __ret = traits_type::eof();
- const bool __testeof =
- traits_type::eq_int_type(this->underflow(), __ret);
+ const bool __testeof = traits_type::eq_int_type(this->underflow(),
+ __ret);
if (!__testeof && _M_in_cur < _M_in_end)
{
__ret = traits_type::to_int_type(*_M_in_cur);
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc
new file mode 100644
index 00000000000..de6e1339a0e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc
@@ -0,0 +1,54 @@
+// 2003-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+void test02()
+{
+ using namespace std;
+ bool test = true;
+ const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it
+
+ locale loc;
+ filebuf ob;
+ VERIFY( ob.getloc() == loc );
+ ob.open(name_01, ios_base::in);
+ VERIFY( ob.is_open() );
+
+ typedef streambuf::pos_type pos_type;
+ pos_type bad = pos_type(streambuf::off_type(-1));
+ pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in);
+ VERIFY( p != bad);
+
+ // 1 "if file is not positioned at its beginning" fails...
+ locale loc_de = __gnu_cxx_test::try_named_locale("de_DE");
+ locale ret = ob.pubimbue(loc_de);
+ VERIFY( ob.getloc() == loc );
+}
+
+main()
+{
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc
new file mode 100644
index 00000000000..1899278d415
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc
@@ -0,0 +1,55 @@
+// 2003-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+class state_codecvt : public std::codecvt<char, char, std::mbstate_t>
+{
+protected:
+ int
+ do_encoding() const throw()
+ { return -1; }
+};
+
+void test03()
+{
+ using namespace std;
+ bool test = true;
+
+ locale loc_s(locale::classic(), new state_codecvt);
+ filebuf ob;
+ ob.pubimbue(loc_s);
+ VERIFY( ob.getloc() == loc_s );
+
+ // 2 "if encoding of current locale is state dependent" fails...
+ locale loc_c = locale::classic();
+ locale ret = ob.pubimbue(loc_s);
+ VERIFY( ob.getloc() == loc_s );
+}
+
+main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/1.cc
new file mode 100644
index 00000000000..621799e513f
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/1.cc
@@ -0,0 +1,45 @@
+// 981208 bkoz test functionality of basic_stringbuf for char_type == char
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+std::wfilebuf fbuf;
+
+// test the filebuf locale settings
+void test02()
+{
+ std::locale loc_c = std::locale::classic();
+ loc_c = fbuf.getloc();
+ fbuf.pubimbue(loc_c); //This should initialize _M_init to true
+ std::locale loc_tmp = fbuf.getloc();
+ VERIFY( loc_tmp == loc_c );
+}
+
+int main()
+{
+ test02();
+ return 0;
+}
+
+
+
+// more candy!!!
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc
new file mode 100644
index 00000000000..4acff8123e7
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc
@@ -0,0 +1,54 @@
+// 2003-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+void test02()
+{
+ using namespace std;
+ bool test = true;
+ const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it
+
+ locale loc;
+ wfilebuf ob;
+ VERIFY( ob.getloc() == loc );
+ ob.open(name_01, ios_base::in);
+ VERIFY( ob.is_open() );
+
+ typedef streambuf::pos_type pos_type;
+ pos_type bad = pos_type(streambuf::off_type(-1));
+ pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in);
+ VERIFY( p != bad);
+
+ // 1 "if file is not positioned at its beginning" fails...
+ locale loc_de = __gnu_cxx_test::try_named_locale("de_DE");
+ locale ret = ob.pubimbue(loc_de);
+ VERIFY( ob.getloc() == loc );
+}
+
+main()
+{
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc
new file mode 100644
index 00000000000..393732bee36
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc
@@ -0,0 +1,55 @@
+// 2003-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+class state_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t>
+{
+protected:
+ int
+ do_encoding() const throw()
+ { return -1; }
+};
+
+void test03()
+{
+ using namespace std;
+ bool test = true;
+
+ locale loc_s(locale::classic(), new state_codecvt);
+ wfilebuf ob;
+ ob.pubimbue(loc_s);
+ VERIFY( ob.getloc() == loc_s );
+
+ // 2 "if encoding of current locale is state dependent" fails...
+ locale loc_c = locale::classic();
+ locale ret = ob.pubimbue(loc_s);
+ VERIFY( ob.getloc() == loc_s );
+}
+
+main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/9322.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/9322.cc
new file mode 100644
index 00000000000..1b083fd023a
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/9322.cc
@@ -0,0 +1,53 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+// libstdc++/9322
+void test07()
+{
+ using std::locale;
+ bool test = true;
+
+ locale loc;
+ std::wfilebuf ob;
+ VERIFY( ob.getloc() == loc );
+
+ locale::global(__gnu_cxx_test::try_named_locale("en_US"));
+ VERIFY( ob.getloc() == loc );
+
+ locale loc_de = __gnu_cxx_test::try_named_locale("de_DE");
+ locale ret = ob.pubimbue(loc_de);
+ VERIFY( ob.getloc() == loc_de );
+ VERIFY( ret == loc );
+
+ locale::global(loc);
+ VERIFY( ob.getloc() == loc_de );
+}
+
+main()
+{
+ test07();
+ return 0;
+}
OpenPOWER on IntegriCloud