diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/istream.tcc | 218 | ||||
-rw-r--r-- | libstdc++-v3/include/std/std_istream.h | 41 | ||||
-rw-r--r-- | libstdc++-v3/src/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/src/Makefile.in | 5 | ||||
-rw-r--r-- | libstdc++-v3/src/istream.cc | 405 |
6 files changed, 538 insertions, 145 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6ad6a596f80..62f996c11d9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2004-11-08 Paolo Carlini <pcarlini@suse.de> + + * include/bits/istream.tcc (getline(char_type*, streamsize, + char_type), ignore(streamsize), ignore(streamsize, int_type)): + Restore a generic version of the functions, not using the + protected members of basic_streambuf. + * include/std/std_istream.h (getline(char_type*, streamsize, + char_type), ignore(streamsize), ignore(streamsize, int_type)): + Declare optimized specializations for char and wchar_t. + * src/istream.cc: New file, define the latter. + * src/Makefile.am: Add. + * src/Makefile.in: Regenerate. + 2004-11-07 Paolo Carlini <pcarlini@suse.de> * testsuite/performance/27_io/ifstream_getline-2.cc: New. diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 2399b8b1e35..b467376b789 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -584,61 +584,43 @@ namespace std ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); if (__cerb) - { + { try - { - const int_type __idelim = traits_type::to_int_type(__delim); - const int_type __eof = traits_type::eof(); - __streambuf_type* __sb = this->rdbuf(); - int_type __c = __sb->sgetc(); - - while (_M_gcount + 1 < __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 - _M_gcount - - 1)); - if (__size > 1) - { - const char_type* __p = traits_type::find(__sb->gptr(), - __size, - __delim); - if (__p) - __size = __p - __sb->gptr(); - traits_type::copy(__s, __sb->gptr(), __size); - __s += __size; - __sb->gbump(__size); - _M_gcount += __size; - __c = __sb->sgetc(); - } - else - { - *__s++ = traits_type::to_char_type(__c); - ++_M_gcount; - __c = __sb->snextc(); - } - } - - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (traits_type::eq_int_type(__c, __idelim)) - { - ++_M_gcount; - __sb->sbumpc(); - } - else - __err |= ios_base::failbit; - } - catch(...) - { this->_M_setstate(ios_base::badbit); } - } + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + __c = __sb->snextc(); + ++_M_gcount; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (traits_type::eq_int_type(__c, __idelim)) + { + __sb->sbumpc(); + ++_M_gcount; + } + else + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } *__s = char_type(); if (!_M_gcount) - __err |= ios_base::failbit; + __err |= ios_base::failbit; if (__err) - this->setstate(__err); + this->setstate(__err); return *this; } @@ -680,48 +662,31 @@ namespace std { if (__n == 1) return ignore(); - + _M_gcount = 0; sentry __cerb(*this, true); if (__cerb && __n > 0) - { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - try - { - const int_type __eof = traits_type::eof(); - __streambuf_type* __sb = this->rdbuf(); - int_type __c = __sb->sgetc(); - - const bool __bound = __n != numeric_limits<streamsize>::max(); - if (__bound) - --__n; - while (_M_gcount <= __n - && !traits_type::eq_int_type(__c, __eof)) - { - streamsize __size = __sb->egptr() - __sb->gptr(); - if (__bound) - __size = std::min(__size, streamsize(__n - _M_gcount + 1)); - - if (__size > 1) - { - __sb->gbump(__size); - _M_gcount += __size; - __c = __sb->sgetc(); - } - else - { - ++_M_gcount; - __c = __sb->snextc(); - } - } + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __eof; + + if (__n != numeric_limits<streamsize>::max()) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) + ++_M_gcount; if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - } - catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); - } + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } return *this; } @@ -736,56 +701,31 @@ namespace std _M_gcount = 0; sentry __cerb(*this, true); if (__cerb && __n > 0) - { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - try - { - const char_type __cdelim = traits_type::to_char_type(__delim); - const int_type __eof = traits_type::eof(); - __streambuf_type* __sb = this->rdbuf(); - int_type __c = __sb->sgetc(); - - const bool __bound = __n != numeric_limits<streamsize>::max(); - if (__bound) - --__n; - while (_M_gcount <= __n - && !traits_type::eq_int_type(__c, __eof) - && !traits_type::eq_int_type(__c, __delim)) - { - streamsize __size = __sb->egptr() - __sb->gptr(); - if (__bound) - __size = std::min(__size, streamsize(__n - _M_gcount + 1)); - - if (__size > 1) - { - const char_type* __p = traits_type::find(__sb->gptr(), - __size, - __cdelim); - if (__p) - __size = __p - __sb->gptr(); - __sb->gbump(__size); - _M_gcount += __size; - __c = __sb->sgetc(); - } - else - { - ++_M_gcount; - __c = __sb->snextc(); - } - } - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (traits_type::eq_int_type(__c, __delim)) - { - ++_M_gcount; - __sb->sbumpc(); - } - } - catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); - } + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __eof; + + if (__n != numeric_limits<streamsize>::max()) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) + { + ++_M_gcount; + if (traits_type::eq_int_type(__c, __delim)) + break; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } return *this; } diff --git a/libstdc++-v3/include/std/std_istream.h b/libstdc++-v3/include/std/std_istream.h index 65f9e6c3034..28b0fdd5c60 100644 --- a/libstdc++-v3/include/std/std_istream.h +++ b/libstdc++-v3/include/std/std_istream.h @@ -574,7 +574,40 @@ namespace std explicit basic_istream(): _M_gcount(streamsize(0)) { } }; + + // Explicit specialization declarations, defined in src/istream.cc. + template<> + basic_istream<char>& + basic_istream<char>:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n); + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n, int_type __delim); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n); + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n, int_type __delim); +#endif + /** * @brief Performs setup work for input streams. * @@ -693,13 +726,13 @@ namespace std operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); template<class _Traits> - basic_istream<char,_Traits>& - operator>>(basic_istream<char,_Traits>& __in, unsigned char* __s) + basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s) { return (__in >> reinterpret_cast<char*>(__s)); } template<class _Traits> - basic_istream<char,_Traits>& - operator>>(basic_istream<char,_Traits>& __in, signed char* __s) + basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, signed char* __s) { return (__in >> reinterpret_cast<char*>(__s)); } //@} diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index b2ca5f6201d..67e17cf7879 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -126,6 +126,7 @@ sources = \ ext-inst.cc \ io-inst.cc \ istream-inst.cc \ + istream.cc \ locale-inst.cc \ locale-misc-inst.cc \ misc-inst.cc \ diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index eb0b0c68f5a..e49698c903e 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -71,8 +71,8 @@ am__objects_3 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ locale.lo locale_init.lo locale_facets.lo localename.lo \ stdexcept.lo strstream.lo tree.lo allocator-inst.lo \ concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \ - istream-inst.lo locale-inst.lo locale-misc-inst.lo misc-inst.lo \ - ostream-inst.lo sstream-inst.lo streambuf-inst.lo \ + istream-inst.lo istream.lo locale-inst.lo locale-misc-inst.lo \ + misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \ string-inst.lo valarray-inst.lo wlocale-inst.lo \ wstring-inst.lo $(am__objects_1) $(am__objects_2) am_libstdc___la_OBJECTS = $(am__objects_3) @@ -336,6 +336,7 @@ sources = \ ext-inst.cc \ io-inst.cc \ istream-inst.cc \ + istream.cc \ locale-inst.cc \ locale-misc-inst.cc \ misc-inst.cc \ diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc new file mode 100644 index 00000000000..7725ab4c138 --- /dev/null +++ b/libstdc++-v3/src/istream.cc @@ -0,0 +1,405 @@ +// Input streams -*- C++ -*- + +// Copyright (C) 2004 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 +// 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. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#include <istream> + +namespace std +{ + template<> + basic_istream<char>& + basic_istream<char>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __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 - _M_gcount + - 1)); + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + } + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __idelim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n) + { + if (__n == 1) + return ignore(); + + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + const bool __bound = __n != numeric_limits<streamsize>::max(); + if (__bound) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c, __eof)) + { + streamsize __size = __sb->egptr() - __sb->gptr(); + if (__bound) + __size = std::min(__size, streamsize(__n - _M_gcount + 1)); + + if (__size > 1) + { + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + ++_M_gcount; + __c = __sb->snextc(); + } + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n, int_type __delim) + { + if (traits_type::eq_int_type(__delim, traits_type::eof())) + return ignore(__n); + + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const char_type __cdelim = traits_type::to_char_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + const bool __bound = __n != numeric_limits<streamsize>::max(); + if (__bound) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + streamsize __size = __sb->egptr() - __sb->gptr(); + if (__bound) + __size = std::min(__size, streamsize(__n - _M_gcount + 1)); + + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __cdelim); + if (__p) + __size = __p - __sb->gptr(); + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + ++_M_gcount; + __c = __sb->snextc(); + } + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __delim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __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 - _M_gcount + - 1)); + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + } + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __idelim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n) + { + if (__n == 1) + return ignore(); + + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + const bool __bound = __n != numeric_limits<streamsize>::max(); + if (__bound) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c, __eof)) + { + streamsize __size = __sb->egptr() - __sb->gptr(); + if (__bound) + __size = std::min(__size, streamsize(__n - _M_gcount + 1)); + + if (__size > 1) + { + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + ++_M_gcount; + __c = __sb->snextc(); + } + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n, int_type __delim) + { + if (traits_type::eq_int_type(__delim, traits_type::eof())) + return ignore(__n); + + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const char_type __cdelim = traits_type::to_char_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + const bool __bound = __n != numeric_limits<streamsize>::max(); + if (__bound) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + streamsize __size = __sb->egptr() - __sb->gptr(); + if (__bound) + __size = std::min(__size, streamsize(__n - _M_gcount + 1)); + + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __cdelim); + if (__p) + __size = __p - __sb->gptr(); + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + ++_M_gcount; + __c = __sb->snextc(); + } + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __delim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } +#endif +} // namespace std |