diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-17 09:04:14 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-17 09:04:14 +0000 |
commit | 5712dd7d701141a2862027dcc5fee5a058d32422 (patch) | |
tree | ea625306475111f10944bfe90cf2e54e6c2aaf6c /libstdc++-v3/src | |
parent | aaa6a523451c253e394f4cc2ce9908fad8a42a2d (diff) | |
download | ppe42-gcc-5712dd7d701141a2862027dcc5fee5a058d32422.tar.gz ppe42-gcc-5712dd7d701141a2862027dcc5fee5a058d32422.zip |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@90801 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/istream.cc | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc index 7725ab4c138..462824dada9 100644 --- a/libstdc++-v3/src/istream.cc +++ b/libstdc++-v3/src/istream.cc @@ -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 |