diff options
author | Paolo Carlini <pcarlini@suse.de> | 2005-07-25 08:47:33 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2005-07-25 08:47:33 +0000 |
commit | ceed88b1315e5d0abe7d5cf3e72f7a478151d78e (patch) | |
tree | 87d3c80e2398847cef0634f8a19a029b5b39d898 /libstdc++-v3/src | |
parent | 0dc42b03d364d14f6e31d4021201f8a1d6323da6 (diff) | |
download | gcc-ceed88b1315e5d0abe7d5cf3e72f7a478151d78e.zip gcc-ceed88b1315e5d0abe7d5cf3e72f7a478151d78e.tar.gz gcc-ceed88b1315e5d0abe7d5cf3e72f7a478151d78e.tar.bz2 |
re PR libstdc++/22515 (operator>>(istream, string/CharT*) can be faster)
2005-07-24 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/22515
* include/bits/basic_string.h: Declare the specialization
operator>>(basic_istream<char>&, basic_string<char>&).
* include/std/std_istream.h: Declate the specialization
operator>>(basic_istream<char>&, char*).
* include/std/std_streambuf.h (basic_streambuf): Add friend
declarations for the above.
* src/istream.cc: Define the above.
* testsuite/27_io/basic_istream/extractors_character/char/4.cc: New.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/4.cc:
Likewise.
* testsuite/performance/27_io/ifstream_extract_chars.cc: Likewise.
From-SVN: r102353
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/istream.cc | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc index e8da16c..15ff41a 100644 --- a/libstdc++-v3/src/istream.cc +++ b/libstdc++-v3/src/istream.cc @@ -185,6 +185,157 @@ namespace std template<> basic_istream<char>& + operator>>(basic_istream<char>& __in, char* __s) + { + 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; + + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Figure out how many characters to extract. + streamsize __num = __in.width(); + if (__num <= 0) + __num = numeric_limits<streamsize>::max(); + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __num - 1 + && !__traits_type::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + __traits_type::to_char_type(__c))) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__num - __extracted + - 1)); + if (__size > 1) + { + __size = (__ct.scan_is(ctype_base::space, + __sb->gptr() + 1, + __sb->gptr() + __size) + - __sb->gptr()); + __traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + *__s++ = __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 68. Extractors for char* should store null at end + *__s = __char_type(); + __in.width(0); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<> + basic_istream<char>& + operator>>(basic_istream<char>& __in, basic_string<char>& __str) + { + 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; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + __str.erase(); + 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_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + __traits_type::to_char_type(__c))) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + __size = (__ct.scan_is(ctype_base::space, + __sb->gptr() + 1, + __sb->gptr() + __size) + - __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; + __in.width(0); + } + 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; + } + + template<> + basic_istream<char>& getline(basic_istream<char>& __in, basic_string<char>& __str, char __delim) { |