From: Benjamin Kosnik Date: Tue, 30 Apr 2002 07:22:11 +0000 (+0000) Subject: re PR libstdc++/5280 (Problems with named locales and iostreams (gnulocale)) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5c352a47a6d4a1a1877ff5fc9e43d42848c05e31;p=gcc.git re PR libstdc++/5280 (Problems with named locales and iostreams (gnulocale)) 2002-04-29 Benjamin Kosnik PR libstdc++/5280 * include/bits/fstream.tcc (basic_filebuf::_M_underflow_common): Check for eof. * include/bits/streambuf_iterator.h: Match stream_iterator.h. (istreambuf_iterator::operator++): Invalidate on eof. (istreambuf_iterator::operator++(int)): Same. (istreambuf_iterator::operator*): Same. From-SVN: r52933 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ee41e414966..76ab32d1134 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2002-04-29 Benjamin Kosnik + + PR libstdc++/5280 + * include/bits/fstream.tcc (basic_filebuf::_M_underflow_common): + Check for eof. + * include/bits/streambuf_iterator.h: Match stream_iterator.h. + (istreambuf_iterator::operator++): Invalidate on eof. + (istreambuf_iterator::operator++(int)): Same. + (istreambuf_iterator::operator*): Same. + 2002-04-29 Rainer Orth * testsuite/lib/libstdc++-v3-dg.exp (libstdc++-v3-init): Set all diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 2ca89c32fc2..910209a1bf1 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -227,11 +227,15 @@ namespace std // Check for unbuffered stream. if (_M_buf_size == 1) { - __ret = _M_file.sys_getc(); - *_M_in_cur = traits_type::to_char_type(__ret); - _M_set_determinate(1); - if (__testout) - _M_out_cur = _M_in_cur; + int_type __c = _M_file.sys_getc(); + if (__c != __ret) + { + __ret = __c; + *_M_in_cur = traits_type::to_char_type(__c); + _M_set_determinate(1); + if (__testout) + _M_out_cur = _M_in_cur; + } return __ret; } diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 88ae25eab18..f7317b2e481 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -1,6 +1,7 @@ // Streambuf iterators -// 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 @@ -41,60 +42,6 @@ namespace std { - template - class ostreambuf_iterator - : public iterator - { - public: - // Types: - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_streambuf<_CharT, _Traits> streambuf_type; - typedef basic_ostream<_CharT, _Traits> ostream_type; - - private: - streambuf_type* _M_sbuf; - bool _M_failed; - - public: - inline - ostreambuf_iterator(ostream_type& __s) throw () - : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } - - ostreambuf_iterator(streambuf_type* __s) throw () - : _M_sbuf(__s), _M_failed(!_M_sbuf) { } - - ostreambuf_iterator& - operator=(_CharT __c); - - ostreambuf_iterator& - operator*() throw() - { return *this; } - - ostreambuf_iterator& - operator++(int) throw() - { return *this; } - - ostreambuf_iterator& - operator++() throw() - { return *this; } - - bool - failed() const throw() - { return _M_failed; } - }; - - template - inline ostreambuf_iterator<_CharT, _Traits>& - ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c) - { - if (!_M_failed && - _Traits::eq_int_type(_M_sbuf->sputc(__c),_Traits::eof())) - _M_failed = true; - return *this; - } - - // 24.5.3 Template class istreambuf_iterator template class istreambuf_iterator @@ -117,12 +64,12 @@ namespace std // the "end of stream" iterator value. // NB: This implementation assumes the "end of stream" value // is EOF, or -1. - streambuf_type* _M_sbuf; + mutable streambuf_type* _M_sbuf; int_type _M_c; public: istreambuf_iterator() throw() - : _M_sbuf(NULL), _M_c(-2) { } + : _M_sbuf(0), _M_c(-2) { } istreambuf_iterator(istream_type& __s) throw() : _M_sbuf(__s.rdbuf()), _M_c(-2) { } @@ -137,22 +84,25 @@ namespace std operator*() const { // The result of operator*() on an end of stream is undefined. - char_type __ret; - if (_M_sbuf && _M_c != static_cast(-2)) - __ret = _M_c; - else if (_M_sbuf) - __ret = traits_type::to_char_type(_M_sbuf->sgetc()); - else - __ret = static_cast(traits_type::eof()); - return __ret; + int_type __ret = traits_type::eof(); + if (_M_sbuf) + { + if (_M_c != static_cast(-2)) + __ret = _M_c; + else + if ((__ret = _M_sbuf->sgetc()) == traits_type::eof()) + _M_sbuf = 0; + } + return traits_type::to_char_type(__ret); } istreambuf_iterator& operator++() { - if (_M_sbuf) - _M_sbuf->sbumpc(); - _M_c = -2; + if (_M_sbuf && _M_sbuf->sbumpc() == traits_type::eof()) + _M_sbuf = 0; + else + _M_c = -2; return *this; } @@ -160,30 +110,22 @@ namespace std operator++(int) { istreambuf_iterator __old = *this; - if (_M_sbuf) - __old._M_c = _M_sbuf->sbumpc(); - _M_c = -2; + if (_M_sbuf && (__old._M_c = _M_sbuf->sbumpc()) == traits_type::eof()) + _M_sbuf = 0; + else + _M_c = -2; return __old; } - bool - equal(const istreambuf_iterator& __b) - { - int_type __eof = traits_type::eof(); - bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof; - bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof; - return (__thiseof && __beof || (!__thiseof && !__beof)); - } - #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS // 110 istreambuf_iterator::equal not const // NB: there is also number 111 (NAD, Future) pending on this function. bool equal(const istreambuf_iterator& __b) const { - int_type __eof = traits_type::eof(); - bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof; - bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof; + const int_type __eof = traits_type::eof(); + bool __thiseof = traits_type::eq_int_type(this->operator*(), __eof); + bool __beof = traits_type::eq_int_type(__b.operator*(), __eof); return (__thiseof && __beof || (!__thiseof && !__beof)); } #endif @@ -200,5 +142,58 @@ namespace std operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { return !__a.equal(__b); } + + template + class ostreambuf_iterator + : public iterator + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + + public: + inline + ostreambuf_iterator(ostream_type& __s) throw () + : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } + + ostreambuf_iterator(streambuf_type* __s) throw () + : _M_sbuf(__s), _M_failed(!_M_sbuf) { } + + ostreambuf_iterator& + operator=(_CharT __c); + + ostreambuf_iterator& + operator*() throw() + { return *this; } + + ostreambuf_iterator& + operator++(int) throw() + { return *this; } + + ostreambuf_iterator& + operator++() throw() + { return *this; } + + bool + failed() const throw() + { return _M_failed; } + }; + + template + inline ostreambuf_iterator<_CharT, _Traits>& + ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) + _M_failed = true; + return *this; + } } // namespace std #endif