OSDN Git Service

2004-11-17 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Nov 2004 09:04:14 +0000 (09:04 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Nov 2004 09:04:14 +0000 (09:04 +0000)
* include/bits/istream.tcc (getline(basic_istream<>&, basic_string<>&,
_CharT)): Remove temporary kludge for libstdc++/15002.
* include/std/std_streambuf.h (class basic_streambuf): Declare
getline(basic_istream<>&, basic_string<>&, _CharT) as friend.
* include/bits/basic_string.h (getline(basic_istream<>&,
basic_string<>&, _CharT)): Declare optimized specializations for
char and wchar_t, using protected members of basic_streambuf.
* src/istream.cc: Define the latter.

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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/std/std_streambuf.h
libstdc++-v3/src/istream.cc

index 78884ef..ab93497 100644 (file)
@@ -1,3 +1,14 @@
+2004-11-17  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/istream.tcc (getline(basic_istream<>&, basic_string<>&,
+       _CharT)): Remove temporary kludge for libstdc++/15002.
+       * include/std/std_streambuf.h (class basic_streambuf): Declare
+       getline(basic_istream<>&, basic_string<>&, _CharT) as friend.
+       * include/bits/basic_string.h (getline(basic_istream<>&,
+       basic_string<>&, _CharT)): Declare optimized specializations for
+       char and wchar_t, using protected members of basic_streambuf.
+       * src/istream.cc: Define the latter.
+
 2004-11-16  Jonathan Wakely  <redi@gcc.gnu.org>
 
        * docs/html/19_diagnostics/howto.html: Document change from
index e242d0f..ecca1f5 100644 (file)
@@ -2286,7 +2286,7 @@ namespace std
     inline bool
     operator<=(const _CharT* __lhs,
               const basic_string<_CharT, _Traits, _Alloc>& __rhs)
-  { return __rhs.compare(__lhs) >= 0; }
+    { return __rhs.compare(__lhs) >= 0; }
 
   // operator >=
   /**
@@ -2382,7 +2382,7 @@ namespace std
    *  delim was encountered, it is extracted but not stored into @a str.
    */
   template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_istream<_CharT,_Traits>&
+    basic_istream<_CharT, _Traits>&
     getline(basic_istream<_CharT, _Traits>& __is,
            basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
 
@@ -2399,9 +2399,21 @@ namespace std
    *  encountered, it is extracted but not stored into @a str.
    */
   template<typename _CharT, typename _Traits, typename _Alloc>
-    inline basic_istream<_CharT,_Traits>&
+    inline basic_istream<_CharT, _Traits>&
     getline(basic_istream<_CharT, _Traits>& __is,
            basic_string<_CharT, _Traits, _Alloc>& __str);
+    
+  template<>
+    basic_istream<char>&
+    getline(basic_istream<char>& __in, basic_string<char>& __str,
+           char __delim);
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<>
+    basic_istream<wchar_t>&
+    getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
+           wchar_t __delim);
+#endif  
 } // namespace std
 
 #endif /* _BASIC_STRING_H */
index b467376..1ed3e8d 100644 (file)
@@ -1160,10 +1160,7 @@ namespace std
        {
          try
            {
-             // Avoid reallocation for common case.
              __str.erase();
-             _CharT __buf[128];
-             __size_type __len = 0;
              const __int_type __idelim = _Traits::to_int_type(__delim);
              const __int_type __eof = _Traits::eof();
              __streambuf_type* __sb = __in.rdbuf();
@@ -1173,16 +1170,10 @@ namespace std
                     && !_Traits::eq_int_type(__c, __eof)
                     && !_Traits::eq_int_type(__c, __idelim))
                {
-                 if (__len == sizeof(__buf) / sizeof(_CharT))
-                   {
-                     __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
-                     __len = 0;
-                   }
-                 __buf[__len++] = _Traits::to_char_type(__c);
+                 __str += _Traits::to_char_type(__c);
                  ++__extracted;
                  __c = __sb->snextc();
                }
-             __str.append(__buf, __len);
 
              if (_Traits::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
index 23da7b9..eed1776 100644 (file)
@@ -154,7 +154,12 @@ namespace std
       friend streamsize
       __copy_streambufs<>(__streambuf_type* __sbin,
                          __streambuf_type* __sbout);
-      
+
+      template<typename _CharT2, typename _Traits2, typename _Alloc>
+        friend basic_istream<_CharT2, _Traits2>&
+        getline(basic_istream<_CharT2, _Traits2>&,
+               basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2);
+
     protected:
       //@{
       /**
index 7725ab4..462824d 100644 (file)
@@ -218,6 +218,86 @@ namespace std
       return *this;
     }
 
+  template<>
+    basic_istream<char>&
+    getline(basic_istream<char>& __in, basic_string<char>& __str,
+           char __delim)
+    {
+      typedef basic_istream<char>              __istream_type;
+      typedef __istream_type::int_type         __int_type;
+      typedef __istream_type::char_type                __char_type;
+      typedef __istream_type::traits_type      __traits_type;
+      typedef __istream_type::__streambuf_type  __streambuf_type;
+      typedef __istream_type::__ctype_type     __ctype_type;
+      typedef basic_string<char>               __string_type;
+      typedef __string_type::size_type         __size_type;
+
+      __size_type __extracted = 0;
+      const __size_type __n = __str.max_size();
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      __istream_type::sentry __cerb(__in, true);
+      if (__cerb)
+       {
+         try
+           {
+             __str.erase();
+             const __int_type __idelim = __traits_type::to_int_type(__delim);
+             const __int_type __eof = __traits_type::eof();
+             __streambuf_type* __sb = __in.rdbuf();
+             __int_type __c = __sb->sgetc();
+
+             while (__extracted < __n
+                    && !__traits_type::eq_int_type(__c, __eof)
+                    && !__traits_type::eq_int_type(__c, __idelim))
+               {
+                 streamsize __size = std::min(streamsize(__sb->egptr()
+                                                         - __sb->gptr()),
+                                              streamsize(__n - __extracted));
+                 if (__size > 1)
+                   {
+                     const __char_type* __p = __traits_type::find(__sb->gptr(),
+                                                                  __size,
+                                                                  __delim);
+                     if (__p)
+                       __size = __p - __sb->gptr();
+                     __str.append(__sb->gptr(), __size);
+                     __sb->gbump(__size);
+                     __extracted += __size;
+                     __c = __sb->sgetc();
+                   }
+                 else
+                   {
+                     __str += __traits_type::to_char_type(__c);
+                     ++__extracted;
+                     __c = __sb->snextc();
+                   }             
+               }
+
+             if (__traits_type::eq_int_type(__c, __eof))
+               __err |= ios_base::eofbit;
+             else if (__traits_type::eq_int_type(__c, __idelim))
+               {
+                 ++__extracted;
+                 __sb->sbumpc();
+               }
+             else
+               __err |= ios_base::failbit;
+           }
+         catch(...)
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 91. Description of operator>> and getline() for string<>
+             // might cause endless loop
+             __in._M_setstate(ios_base::badbit);
+           }
+       }
+      if (!__extracted)
+       __err |= ios_base::failbit;
+      if (__err)
+       __in.setstate(__err);
+      return __in;
+    }
+
 #ifdef _GLIBCXX_USE_WCHAR_T
   template<>
     basic_istream<wchar_t>&
@@ -401,5 +481,85 @@ namespace std
        }
       return *this;
     }
+
+  template<>
+    basic_istream<wchar_t>&
+    getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
+           wchar_t __delim)
+    {
+      typedef basic_istream<wchar_t>           __istream_type;
+      typedef __istream_type::int_type         __int_type;
+      typedef __istream_type::char_type                __char_type;
+      typedef __istream_type::traits_type      __traits_type;
+      typedef __istream_type::__streambuf_type  __streambuf_type;
+      typedef __istream_type::__ctype_type     __ctype_type;
+      typedef basic_string<wchar_t>            __string_type;
+      typedef __string_type::size_type         __size_type;
+
+      __size_type __extracted = 0;
+      const __size_type __n = __str.max_size();
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      __istream_type::sentry __cerb(__in, true);
+      if (__cerb)
+       {
+         try
+           {
+             __str.erase();
+             const __int_type __idelim = __traits_type::to_int_type(__delim);
+             const __int_type __eof = __traits_type::eof();
+             __streambuf_type* __sb = __in.rdbuf();
+             __int_type __c = __sb->sgetc();
+
+             while (__extracted < __n
+                    && !__traits_type::eq_int_type(__c, __eof)
+                    && !__traits_type::eq_int_type(__c, __idelim))
+               {
+                 streamsize __size = std::min(streamsize(__sb->egptr()
+                                                         - __sb->gptr()),
+                                              streamsize(__n - __extracted));
+                 if (__size > 1)
+                   {
+                     const __char_type* __p = __traits_type::find(__sb->gptr(),
+                                                                  __size,
+                                                                  __delim);
+                     if (__p)
+                       __size = __p - __sb->gptr();
+                     __str.append(__sb->gptr(), __size);
+                     __sb->gbump(__size);
+                     __extracted += __size;
+                     __c = __sb->sgetc();
+                   }
+                 else
+                   {
+                     __str += __traits_type::to_char_type(__c);
+                     ++__extracted;
+                     __c = __sb->snextc();
+                   }             
+               }
+
+             if (__traits_type::eq_int_type(__c, __eof))
+               __err |= ios_base::eofbit;
+             else if (__traits_type::eq_int_type(__c, __idelim))
+               {
+                 ++__extracted;
+                 __sb->sbumpc();
+               }
+             else
+               __err |= ios_base::failbit;
+           }
+         catch(...)
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 91. Description of operator>> and getline() for string<>
+             // might cause endless loop
+             __in._M_setstate(ios_base::badbit);
+           }
+       }
+      if (!__extracted)
+       __err |= ios_base::failbit;
+      if (__err)
+       __in.setstate(__err);
+      return __in;
+    }
 #endif
 } // namespace std