OSDN Git Service

2002-04-29 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 07:22:11 +0000 (07:22 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 07:22:11 +0000 (07:22 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52933 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/streambuf_iterator.h

index ee41e41..76ab32d 100644 (file)
@@ -1,3 +1,13 @@
+2002-04-29  Benjamin Kosnik  <bkoz@redhat.com>
+
+       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  <ro@TechFak.Uni-Bielefeld.DE>
 
        * testsuite/lib/libstdc++-v3-dg.exp (libstdc++-v3-init): Set all
index 2ca89c3..910209a 100644 (file)
@@ -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;
            }
 
index 88ae25e..f7317b2 100644 (file)
@@ -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
 
 namespace std
 {
-  template<typename _CharT, typename _Traits>
-    class ostreambuf_iterator
-    : public iterator<output_iterator_tag, void, void, void, void>
-    {
-    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<typename _CharT, typename _Traits>
-    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<typename _CharT, typename _Traits>
     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<int_type>(-2))
-         __ret = _M_c;
-       else if (_M_sbuf)
-         __ret = traits_type::to_char_type(_M_sbuf->sgetc()); 
-       else
-         __ret = static_cast<char_type>(traits_type::eof());
-       return __ret;
+       int_type __ret = traits_type::eof();
+       if (_M_sbuf)
+         { 
+           if (_M_c != static_cast<int_type>(-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<typename _CharT, typename _Traits>
+    class ostreambuf_iterator
+    : public iterator<output_iterator_tag, void, void, void, void>
+    {
+    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<typename _CharT, typename _Traits>
+    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