istream.tcc (operator>>(basic_istream<>&, basic_string<>&)): Use a temporary buffer...
authorPaolo Carlini <pcarlini@suse.de>
Thu, 20 May 2004 22:06:40 +0000 (22:06 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 20 May 2004 22:06:40 +0000 (22:06 +0000)
2004-05-20  Paolo Carlini  <pcarlini@suse.de>

* include/bits/istream.tcc (operator>>(basic_istream<>&,
basic_string<>&)): Use a temporary buffer, thus avoiding
reallocation for common case.
* testsuite/21_strings/basic_string/inserters_extractors/char/11.cc:
New.
* testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc:
Likewise.

* include/bits/istream.tcc: Const-ification of a few variables.

* include/bits/ostream.tcc: Trivial formatting fixes and
const-ification of some variables.

From-SVN: r82070

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/ostream.tcc
libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc [new file with mode: 0644]
libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc [new file with mode: 0644]

index a181b46..1baf1de 100644 (file)
@@ -1,3 +1,18 @@
+2004-05-20  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/istream.tcc (operator>>(basic_istream<>&,
+       basic_string<>&)): Use a temporary buffer, thus avoiding
+       reallocation for common case.
+       * testsuite/21_strings/basic_string/inserters_extractors/char/11.cc:
+       New.
+       * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc:
+       Likewise.
+
+       * include/bits/istream.tcc: Const-ification of a few variables.
+
+       * include/bits/ostream.tcc: Trivial formatting fixes and
+       const-ification of some variables.
+
 2004-05-20  Benjamin Kosnik  <bkoz@redhat.com>
 
        PR libstdc++/15123
index 21f809d..5469005 100644 (file)
@@ -478,7 +478,7 @@ namespace std
        {
          try
            {
-             int_type __cb = this->rdbuf()->sbumpc();
+             const int_type __cb = this->rdbuf()->sbumpc();
              // 27.6.1.1 paragraph 3
              if (!traits_type::eq_int_type(__cb, traits_type::eof()))
                {
@@ -876,7 +876,8 @@ namespace std
          if (!this->fail())
            {
              // 136.  seekp, seekg setting wrong streams?
-             pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::in);
+             const pos_type __p = this->rdbuf()->pubseekpos(__pos,
+                                                            ios_base::in);
 
              // 129. Need error indication from seekp() and seekg()
              if (__p == pos_type(off_type(-1)))
@@ -903,8 +904,8 @@ namespace std
          if (!this->fail())
            {
              // 136.  seekp, seekg setting wrong streams?
-             pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
-                                                      ios_base::in);
+             const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
+                                                            ios_base::in);
 
              // 129. Need error indication from seekp() and seekg()
              if (__p == pos_type(off_type(-1)))
@@ -924,13 +925,15 @@ namespace std
     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
     {
       typedef basic_istream<_CharT, _Traits>           __istream_type;
+      typedef typename __istream_type::int_type         __int_type;
+
       typename __istream_type::sentry __cerb(__in, false);
       if (__cerb)
        {
          ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try
            {
-             typename __istream_type::int_type __cb = __in.rdbuf()->sbumpc();
+             const __int_type __cb = __in.rdbuf()->sbumpc();
              if (!_Traits::eq_int_type(__cb, _Traits::eof()))
                __c = _Traits::to_char_type(__cb);
              else
@@ -1043,11 +1046,13 @@ namespace std
        {
          try
            {
+             // Avoid reallocation for common case.
              __str.erase();
-             streamsize __w = __in.width();
-             __size_type __n;
-             __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
-
+             _CharT __buf[128];
+             __size_type __len = 0;          
+             const streamsize __w = __in.width();
+             const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
+                                             : __str.max_size();
              const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
              const __int_type __eof = _Traits::eof();
              __streambuf_type* __sb = __in.rdbuf();
@@ -1057,10 +1062,17 @@ namespace std
                     && !_Traits::eq_int_type(__c, __eof)
                     && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
                {
-                 __str += _Traits::to_char_type(__c);
+                 if (__len == sizeof(__buf) / sizeof(_CharT))
+                   {
+                     __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
+                     __len = 0;
+                   }
+                 __buf[__len++] = _Traits::to_char_type(__c);
                  ++__extracted;
                  __c = __sb->snextc();
                }
+             __str.append(__buf, __len);
+
              if (_Traits::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
              __in.width(0);
@@ -1102,7 +1114,7 @@ namespace std
        {
          try
            {
-             // Avoid reallocation for common case.          
+             // Avoid reallocation for common case.
              __str.erase();
              _CharT __buf[128];
              __size_type __len = 0;
index 1ff14a6..5510ea3 100644 (file)
@@ -1,6 +1,6 @@
 // ostream classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -129,12 +129,13 @@ namespace std
          try
            {
              bool __b = false;
-             char_type __c = this->fill();
-             ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
+             const char_type __c = this->fill();
+             const ios_base::fmtflags __fmt = (this->flags()
+                                               & ios_base::basefield);
              const __num_put_type& __np = __check_facet(this->_M_num_put);
              if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
                {
-                 unsigned long __l = static_cast<unsigned long>(__n);
+                 const unsigned long __l = static_cast<unsigned long>(__n);
                  __b = __np.put(*this, *this, __c, __l).failed();
                }
              else
@@ -186,13 +187,14 @@ namespace std
          try
            {
              bool __b = false;
-             char_type __c = this->fill();
-             ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
+             const char_type __c = this->fill();
+             const ios_base::fmtflags __fmt = (this->flags()
+                                               & ios_base::basefield);
              const __num_put_type& __np = __check_facet(this->_M_num_put);
              if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
                {
-                 unsigned long long __l;
-                 __l = static_cast<unsigned long long>(__n);
+                 const unsigned long long __l = (static_cast<
+                                                 unsigned long long>(__n));
                  __b = __np.put(*this, *this, __c, __l).failed();
                }
              else
@@ -342,7 +344,7 @@ namespace std
          ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try
            {
-             int_type __put = this->rdbuf()->sputc(__c);
+             const int_type __put = this->rdbuf()->sputc(__c);
              if (traits_type::eq_int_type(__put, traits_type::eof()))
                __err |= ios_base::badbit;
            }
@@ -426,7 +428,8 @@ namespace std
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
              // 136.  seekp, seekg setting wrong streams?
-             pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
+             const pos_type __p = this->rdbuf()->pubseekpos(__pos,
+                                                            ios_base::out);
 
              // 129. Need error indication from seekp() and seekg()
              if (__p == pos_type(off_type(-1)))
@@ -452,8 +455,8 @@ namespace std
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
              // 136.  seekp, seekg setting wrong streams?
-             pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
-                                                      ios_base::out);
+             const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
+                                                            ios_base::out);
 
              // 129. Need error indication from seekp() and seekg()
              if (__p == pos_type(off_type(-1)))
@@ -542,8 +545,9 @@ namespace std
              streamsize __len = static_cast<streamsize>(_Traits::length(__s));
              if (__w > __len)
                {
-                 _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
-                                                                      * __w));
+                 _CharT* __cs = (static_cast<
+                                 _CharT*>(__builtin_alloca(sizeof(_CharT)
+                                                           * __w)));
                  __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
                                                 __s, __w, __len, false);
                  __s = __cs;
@@ -585,8 +589,9 @@ namespace std
              streamsize __len = static_cast<streamsize>(__clen);
              if (__w > __len)
                {
-                 _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
-                                                                      * __w));
+                 _CharT* __cs = (static_cast<
+                                 _CharT*>(__builtin_alloca(sizeof(_CharT)
+                                                           * __w)));
                  __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
                                                 __ws, __w, __len, false);
                  __str = __cs;
@@ -653,7 +658,8 @@ namespace std
          // 25. String operator<< uses width() value wrong
          if (__w > __len)
            {
-             _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+             _CharT* __cs = (static_cast<
+                             _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
              __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s,
                                             __w, __len, false);
              __s = __cs;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc
new file mode 100644 (file)
index 0000000..cee596e
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2004 Free Software Foundation
+//
+// 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.
+
+// 21.3.7.9 inserters and extractors
+
+#include <istream>
+#include <string>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+string prepare(string::size_type len, unsigned nchunks)
+{
+  string ret;
+  for (unsigned i = 0; i < nchunks; ++i)
+    {
+      for (string::size_type j = 0; j < len; ++j)
+       ret.push_back('a' + rand() % 26);
+      len *= 2;
+      ret.push_back(' ');
+    }
+  return ret;
+}
+
+void check(istream& stream, const string& str)
+{
+  bool test __attribute__((unused)) = true;
+
+  string chunk;
+  string::size_type index = 0, index_new = 0;
+
+  while (stream >> chunk)
+    {
+      index_new = str.find(' ', index);
+      VERIFY( !str.compare(index, index_new - index, chunk) );
+      index = index_new + 1;
+    }
+  VERIFY( stream.eof() );
+}
+
+// istream& operator>>(istream&, string&)
+void test01()
+{
+  const char filename[] = "inserters_extractors-3.txt";
+
+  const string data = prepare(666, 10);
+
+  ofstream ofstrm;
+  ofstrm.open(filename);
+  ofstrm.write(data.data(), data.size());
+  ofstrm.close();
+
+  ifstream ifstrm;
+  ifstrm.open(filename);
+  check(ifstrm, data);
+  ifstrm.close();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc
new file mode 100644 (file)
index 0000000..ac2e8c3
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2004 Free Software Foundation
+//
+// 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.
+
+// 21.3.7.9 inserters and extractors
+
+#include <istream>
+#include <string>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+wstring prepare(wstring::size_type len, unsigned nchunks)
+{
+  wstring ret;
+  for (unsigned i = 0; i < nchunks; ++i)
+    {
+      for (wstring::size_type j = 0; j < len; ++j)
+       ret.push_back(L'a' + rand() % 26);
+      len *= 2;
+      ret.push_back(L' ');
+    }
+  return ret;
+}
+
+void check(wistream& stream, const wstring& str)
+{
+  bool test __attribute__((unused)) = true;
+
+  wstring chunk;
+  wstring::size_type index = 0, index_new = 0;
+
+  while (stream >> chunk)
+    {
+      index_new = str.find(L' ', index);
+      VERIFY( !str.compare(index, index_new - index, chunk) );
+      index = index_new + 1;
+    }
+  VERIFY( stream.eof() );
+}
+
+// istream& operator>>(istream&, string&)
+void test01()
+{
+  const char filename[] = "inserters_extractors-3.txt";
+
+  const wstring data = prepare(666, 10);
+
+  wofstream ofstrm;
+  ofstrm.open(filename);
+  ofstrm.write(data.data(), data.size());
+  ofstrm.close();
+
+  wifstream ifstrm;
+  ifstrm.open(filename);
+  check(ifstrm, data);
+  ifstrm.close();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}