aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2005-07-25 08:47:33 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2005-07-25 08:47:33 +0000
commitceed88b1315e5d0abe7d5cf3e72f7a478151d78e (patch)
tree87d3c80e2398847cef0634f8a19a029b5b39d898 /libstdc++-v3/src
parent0dc42b03d364d14f6e31d4021201f8a1d6323da6 (diff)
downloadgcc-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.cc151
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)
{