OSDN Git Service

PR c++/19564
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / streambuf_iterator.h
index 027cc89..c743bb3 100644 (file)
@@ -1,6 +1,6 @@
 // Streambuf iterators
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -16,7 +16,7 @@
 
 // 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,
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 // USA.
 
 // As a special exception, you may use this file as part of a free software
 #include <streambuf>
 #include <debug/debug.h>
 
-// NB: Should specialize copy, find algorithms for streambuf iterators.
-
-namespace std
-{
+_GLIBCXX_BEGIN_NAMESPACE(std)
+     
   // 24.5.3 Template class istreambuf_iterator
+  /// Provides input iterator semantics for streambufs.
   template<typename _CharT, typename _Traits>
     class istreambuf_iterator
     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
-                     _CharT*, _CharT&>
+                     _CharT*, _CharT&>
     {
     public:
       // Types:
-      typedef _CharT                                   char_type;
-      typedef _Traits                                  traits_type;
-      typedef typename _Traits::int_type               int_type;
-      typedef basic_streambuf<_CharT, _Traits>                 streambuf_type;
-      typedef basic_istream<_CharT, _Traits>           istream_type;
+      //@{
+      /// Public typedefs
+      typedef _CharT                                   char_type;
+      typedef _Traits                                  traits_type;
+      typedef typename _Traits::int_type               int_type;
+      typedef basic_streambuf<_CharT, _Traits>         streambuf_type;
+      typedef basic_istream<_CharT, _Traits>           istream_type;
+      //@}
+
+      template<typename _CharT2>
+       friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
+                                   ostreambuf_iterator<_CharT2> >::__type
+       copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
+            ostreambuf_iterator<_CharT2>);
+
+      template<typename _CharT2>
+       friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 
+                                              _CharT2*>::__type
+       __copy_aux(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
+                  _CharT2*);
+
+      template<typename _CharT2>
+       friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
+                                   istreambuf_iterator<_CharT2> >::__type
+       find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
+            const _CharT2&);
 
     private:
-      // 24.5.3 istreambuf_iterator 
-      // p 1 
+      // 24.5.3 istreambuf_iterator
+      // p 1
       // If the end of stream is reached (streambuf_type::sgetc()
       // returns traits_type::eof()), the iterator becomes equal to
       // the "end of stream" iterator value.
       // NB: This implementation assumes the "end of stream" value
       // is EOF, or -1.
-      mutable streambuf_type*  _M_sbuf;  
-      int_type                         _M_c;
+      mutable streambuf_type*  _M_sbuf;
+      mutable int_type         _M_c;
 
     public:
-      istreambuf_iterator() throw() 
+      ///  Construct end of input stream iterator.
+      istreambuf_iterator() throw()
       : _M_sbuf(0), _M_c(traits_type::eof()) { }
-      
+
+      ///  Construct start of input stream iterator.
       istreambuf_iterator(istream_type& __s) throw()
       : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
 
+      ///  Construct start of streambuf iterator.
       istreambuf_iterator(streambuf_type* __s) throw()
       : _M_sbuf(__s), _M_c(traits_type::eof()) { }
-       
-      // NB: The result of operator*() on an end of stream is undefined.
-      char_type 
+
+      ///  Return the current character pointed to by iterator.  This returns
+      ///  streambuf.sgetc().  It cannot be assigned.  NB: The result of
+      ///  operator*() on an end of stream is undefined.
+      char_type
       operator*() const
-      { 
+      {
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
        // Dereferencing a past-the-end istreambuf_iterator is a
        // libstdc++ extension
        __glibcxx_requires_cond(!_M_at_eof(),
                                _M_message(__gnu_debug::__msg_deref_istreambuf)
-                               ._M_iterator(*this)); 
+                               ._M_iterator(*this));
 #endif
-       return traits_type::to_char_type(_M_get()); 
+       return traits_type::to_char_type(_M_get());
       }
-       
-      istreambuf_iterator& 
+
+      /// Advance the iterator.  Calls streambuf.sbumpc().
+      istreambuf_iterator&
       operator++()
-      { 
+      {
        __glibcxx_requires_cond(!_M_at_eof(),
                                _M_message(__gnu_debug::__msg_inc_istreambuf)
-                               ._M_iterator(*this)); 
-       const int_type __eof = traits_type::eof();
-       if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
-         _M_sbuf = 0;
-       else
-         _M_c = __eof;
-       return *this; 
+                               ._M_iterator(*this));
+       if (_M_sbuf)
+         {
+           _M_sbuf->sbumpc();
+           _M_c = traits_type::eof();
+         }
+       return *this;
       }
 
+      /// Advance the iterator.  Calls streambuf.sbumpc().
       istreambuf_iterator
       operator++(int)
       {
        __glibcxx_requires_cond(!_M_at_eof(),
                                _M_message(__gnu_debug::__msg_inc_istreambuf)
-                               ._M_iterator(*this)); 
+                               ._M_iterator(*this));
 
-       const int_type __eof = traits_type::eof();
        istreambuf_iterator __old = *this;
-       if (_M_sbuf
-           && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), 
-                                       __eof))
-         _M_sbuf = 0;
-       else
-         _M_c = __eof;
-       return __old; 
+       if (_M_sbuf)
+         {
+           __old._M_c = _M_sbuf->sbumpc();
+           _M_c = traits_type::eof();
+         }
+       return __old;
       }
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 110 istreambuf_iterator::equal not const
       // NB: there is also number 111 (NAD, Future) pending on this function.
-      bool 
+      /// Return true both iterators are end or both are not end.
+      bool
       equal(const istreambuf_iterator& __b) const
       {
        const bool __thiseof = _M_at_eof();
        const bool __beof = __b._M_at_eof();
-       return (__thiseof && __beof || (!__thiseof && !__beof));
+       return ((__thiseof && __beof) || (!__thiseof && !__beof));
       }
 
     private:
-      int_type 
+      int_type
       _M_get() const
-      { 
+      {
        const int_type __eof = traits_type::eof();
        int_type __ret = __eof;
        if (_M_sbuf)
-         { 
+         {
            if (!traits_type::eq_int_type(_M_c, __eof))
              __ret = _M_c;
-           else 
-             if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof))
-               _M_sbuf = 0;
+           else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
+                                              __eof))
+             _M_c = __ret;
+           else
+             _M_sbuf = 0;
          }
        return __ret;
       }
 
-      bool 
+      bool
       _M_at_eof() const
       {
        const int_type __eof = traits_type::eof();
@@ -163,72 +191,210 @@ namespace std
     };
 
   template<typename _CharT, typename _Traits>
-    inline bool 
+    inline bool
     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
               const istreambuf_iterator<_CharT, _Traits>& __b)
     { return __a.equal(__b); }
 
   template<typename _CharT, typename _Traits>
-    inline bool 
+    inline bool
     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
               const istreambuf_iterator<_CharT, _Traits>& __b)
     { return !__a.equal(__b); }
 
+  /// Provides output iterator semantics for streambufs.
   template<typename _CharT, typename _Traits>
     class ostreambuf_iterator
     : public iterator<output_iterator_tag, void, void, void, void>
     {
     public:
       // Types:
+      //@{
+      /// Public typedefs
       typedef _CharT                           char_type;
       typedef _Traits                          traits_type;
       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
       typedef basic_ostream<_CharT, _Traits>   ostream_type;
+      //@}
+
+      template<typename _CharT2>
+       friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
+                                   ostreambuf_iterator<_CharT2> >::__type
+       copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
+            ostreambuf_iterator<_CharT2>);
 
     private:
-      streambuf_type*  _M_sbuf;
-      bool             _M_failed;
+      streambuf_type*  _M_sbuf;
+      bool             _M_failed;
 
     public:
+      ///  Construct output iterator from ostream.
       ostreambuf_iterator(ostream_type& __s) throw ()
       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
-      
+
+      ///  Construct output iterator from streambuf.
       ostreambuf_iterator(streambuf_type* __s) throw ()
       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
 
-      ostreambuf_iterator& 
+      ///  Write character to streambuf.  Calls streambuf.sputc().
+      ostreambuf_iterator&
       operator=(_CharT __c)
       {
-       if (!_M_failed && 
+       if (!_M_failed &&
            _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
          _M_failed = true;
        return *this;
       }
 
-      ostreambuf_iterator& 
+      /// Return *this.
+      ostreambuf_iterator&
       operator*()
       { return *this; }
 
-      ostreambuf_iterator& 
+      /// Return *this.
+      ostreambuf_iterator&
       operator++(int)
       { return *this; }
 
-      ostreambuf_iterator& 
+      /// Return *this.
+      ostreambuf_iterator&
       operator++()
       { return *this; }
 
-      bool 
+      /// Return true if previous operator=() failed.
+      bool
       failed() const throw()
       { return _M_failed; }
 
-      ostreambuf_iterator& 
+      ostreambuf_iterator&
       _M_put(const _CharT* __ws, streamsize __len)
       {
        if (__builtin_expect(!_M_failed, true)
-           && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, false))
+           && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
+                               false))
          _M_failed = true;
        return *this;
       }
     };
-} // namespace std
+
+  // Overloads for streambuf iterators.
+  template<typename _CharT>
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
+                                   ostreambuf_iterator<_CharT> >::__type
+    copy(istreambuf_iterator<_CharT> __first,
+        istreambuf_iterator<_CharT> __last,
+        ostreambuf_iterator<_CharT> __result)
+    {
+      if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
+       {
+         bool __ineof;
+         __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
+         if (!__ineof)
+           __result._M_failed = true;
+       }
+      return __result;
+    }
+
+  template<typename _CharT>
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 
+                                   ostreambuf_iterator<_CharT> >::__type
+    __copy_aux(_CharT* __first, _CharT* __last,
+              ostreambuf_iterator<_CharT> __result)
+    {
+      const streamsize __num = __last - __first;
+      if (__num > 0)
+       __result._M_put(__first, __num);
+      return __result;
+    }
+
+  template<typename _CharT>
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
+                                   ostreambuf_iterator<_CharT> >::__type
+    __copy_aux(const _CharT* __first, const _CharT* __last,
+              ostreambuf_iterator<_CharT> __result)
+    {
+      const streamsize __num = __last - __first;
+      if (__num > 0)
+       __result._M_put(__first, __num);
+      return __result;
+    }
+
+  template<typename _CharT>
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 
+                                   _CharT*>::__type
+    __copy_aux(istreambuf_iterator<_CharT> __first,
+              istreambuf_iterator<_CharT> __last, _CharT* __result)
+    {
+      typedef istreambuf_iterator<_CharT>                  __is_iterator_type;
+      typedef typename __is_iterator_type::traits_type     traits_type;
+      typedef typename __is_iterator_type::streambuf_type  streambuf_type;
+      typedef typename traits_type::int_type               int_type;
+
+      if (__first._M_sbuf && !__last._M_sbuf)
+       {
+         streambuf_type* __sb = __first._M_sbuf;
+         int_type __c = __sb->sgetc();
+         while (!traits_type::eq_int_type(__c, traits_type::eof()))
+           {
+             const streamsize __n = __sb->egptr() - __sb->gptr();
+             if (__n > 1)
+               {
+                 traits_type::copy(__result, __sb->gptr(), __n);
+                 __sb->gbump(__n);
+                 __result += __n;
+                 __c = __sb->underflow();
+               }
+             else
+               {
+                 *__result++ = traits_type::to_char_type(__c);
+                 __c = __sb->snextc();
+               }
+           }
+       }
+      return __result;
+    }
+
+  template<typename _CharT>
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
+                                   istreambuf_iterator<_CharT> >::__type
+    find(istreambuf_iterator<_CharT> __first,
+        istreambuf_iterator<_CharT> __last, const _CharT& __val)
+    {
+      typedef istreambuf_iterator<_CharT>                  __is_iterator_type;
+      typedef typename __is_iterator_type::traits_type     traits_type;
+      typedef typename __is_iterator_type::streambuf_type  streambuf_type;
+      typedef typename traits_type::int_type               int_type;
+
+      if (__first._M_sbuf && !__last._M_sbuf)
+       {
+         const int_type __ival = traits_type::to_int_type(__val);
+         streambuf_type* __sb = __first._M_sbuf;
+         int_type __c = __sb->sgetc();
+         while (!traits_type::eq_int_type(__c, traits_type::eof())
+                && !traits_type::eq_int_type(__c, __ival))
+           {
+             streamsize __n = __sb->egptr() - __sb->gptr();
+             if (__n > 1)
+               {
+                 const _CharT* __p = traits_type::find(__sb->gptr(),
+                                                       __n, __val);
+                 if (__p)
+                   __n = __p - __sb->gptr();
+                 __sb->gbump(__n);
+                 __c = __sb->sgetc();
+               }
+             else
+               __c = __sb->snextc();
+           }
+
+         if (!traits_type::eq_int_type(__c, traits_type::eof()))
+           __first._M_c = __c;
+         else
+           __first._M_sbuf = 0;
+       }
+      return __first;
+    }
+
+_GLIBCXX_END_NAMESPACE
+
 #endif