blob: 55cfe2949b9ce545e746507c0660f973fb189900 [file] [log] [blame]
// Input streams operating on strings-*- C++ -*-
// Copyright (C) 2004-2021 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 27.6.1 Input streams
//
#ifndef _GLIBCXX_USE_CXX11_ABI
// Instantiations in this file use the new SSO std::string ABI unless included
// by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
# define _GLIBCXX_USE_CXX11_ABI 1
#endif
#include <istream>
#include <string>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
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::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::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->__safe_gbump(__size);
__extracted += __size;
__c = __sb->sgetc();
}
else
{
__str += __traits_type::to_char_type(__c);
++__extracted;
__c = __sb->snextc();
}
}
if (__extracted < __n && __traits_type::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
__in.width(0);
}
__catch(__cxxabiv1::__forced_unwind&)
{
__in._M_setstate(ios_base::badbit);
__throw_exception_again;
}
__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)
{
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 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::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->__safe_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(__cxxabiv1::__forced_unwind&)
{
__in._M_setstate(ios_base::badbit);
__throw_exception_again;
}
__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>&
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 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::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->__safe_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(__cxxabiv1::__forced_unwind&)
{
__in._M_setstate(ios_base::badbit);
__throw_exception_again;
}
__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
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace