summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-17 09:04:14 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-17 09:04:14 +0000
commit5712dd7d701141a2862027dcc5fee5a058d32422 (patch)
treeea625306475111f10944bfe90cf2e54e6c2aaf6c /libstdc++-v3/src
parentaaa6a523451c253e394f4cc2ce9908fad8a42a2d (diff)
downloadppe42-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.cc160
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
OpenPOWER on IntegriCloud