From 3adf6cadbbfe23b96f8e53780ae5f1bc28f01077 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 20 May 2004 22:06:40 +0000 Subject: [PATCH] istream.tcc (operator>>(basic_istream<>&, basic_string<>&)): Use a temporary buffer, thus avoiding reallocation for common case. 2004-05-20 Paolo Carlini * 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 | 15 ++++ libstdc++-v3/include/bits/istream.tcc | 34 +++++--- libstdc++-v3/include/bits/ostream.tcc | 40 ++++++---- .../inserters_extractors/char/11.cc | 79 +++++++++++++++++++ .../inserters_extractors/wchar_t/11.cc | 79 +++++++++++++++++++ 5 files changed, 219 insertions(+), 28 deletions(-) create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a181b46aac6..1baf1dede9b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2004-05-20 Paolo Carlini + + * 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 PR libstdc++/15123 diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 21f809d7897..5469005a67f 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -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; diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index 1ff14a66ae3..5510ea3ecc4 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -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(__n); + const unsigned long __l = static_cast(__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(__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(_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(__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 index 00000000000..cee596e5b99 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc @@ -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 +#include +#include +#include + +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 index 00000000000..ac2e8c3a0e2 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc @@ -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 +#include +#include +#include + +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; +} -- 2.30.2