c++, coroutines, contracts: Handle coroutine and void functions [PR110871,PR110872...
[official-gcc.git] / libstdc++-v3 / src / c++98 / istream.cc
blobd1b4444ff2b04d3fe2c537cddb12d6ea01a806ca
1 // Input streams -*- C++ -*-
3 // Copyright (C) 2004-2024 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
26 // ISO C++ 14882: 27.6.1 Input streams
29 #include <istream>
31 namespace std _GLIBCXX_VISIBILITY(default)
33 _GLIBCXX_BEGIN_NAMESPACE_VERSION
35 template<>
36 basic_istream<char>&
37 basic_istream<char>::
38 getline(char_type* __s, streamsize __n, char_type __delim)
40 _M_gcount = 0;
41 ios_base::iostate __err = ios_base::goodbit;
42 sentry __cerb(*this, true);
43 if (__cerb)
45 __try
47 const int_type __idelim = traits_type::to_int_type(__delim);
48 const int_type __eof = traits_type::eof();
49 __streambuf_type* __sb = this->rdbuf();
50 int_type __c = __sb->sgetc();
52 while (_M_gcount + 1 < __n
53 && !traits_type::eq_int_type(__c, __eof)
54 && !traits_type::eq_int_type(__c, __idelim))
56 streamsize __size = std::min(streamsize(__sb->egptr()
57 - __sb->gptr()),
58 streamsize(__n - _M_gcount
59 - 1));
60 if (__size > 1)
62 const char_type* __p = traits_type::find(__sb->gptr(),
63 __size,
64 __delim);
65 if (__p)
66 __size = __p - __sb->gptr();
67 traits_type::copy(__s, __sb->gptr(), __size);
68 __s += __size;
69 __sb->__safe_gbump(__size);
70 _M_gcount += __size;
71 __c = __sb->sgetc();
73 else
75 *__s++ = traits_type::to_char_type(__c);
76 ++_M_gcount;
77 __c = __sb->snextc();
81 if (traits_type::eq_int_type(__c, __eof))
82 __err |= ios_base::eofbit;
83 else if (traits_type::eq_int_type(__c, __idelim))
85 ++_M_gcount;
86 __sb->sbumpc();
88 else
89 __err |= ios_base::failbit;
91 __catch(__cxxabiv1::__forced_unwind&)
93 this->_M_setstate(ios_base::badbit);
94 __throw_exception_again;
96 __catch(...)
97 { this->_M_setstate(ios_base::badbit); }
99 // _GLIBCXX_RESOLVE_LIB_DEFECTS
100 // 243. get and getline when sentry reports failure.
101 if (__n > 0)
102 *__s = char_type();
103 if (!_M_gcount)
104 __err |= ios_base::failbit;
105 if (__err)
106 this->setstate(__err);
107 return *this;
110 template<>
111 basic_istream<char>&
112 basic_istream<char>::
113 ignore(streamsize __n, int_type __delim)
116 // If conversion to int_type changes the value then __delim does not
117 // correspond to a value of type char_type, and so will never match
118 // a character extracted from the input sequence. Just use ignore(n).
119 const int_type chk_delim = traits_type::to_int_type(__delim);
120 const bool matchable = traits_type::eq_int_type(chk_delim, __delim);
121 if (__builtin_expect(!matchable, 0))
122 return ignore(__n);
123 // Now we know that __delim is a valid char_type value, so it's safe
124 // for the code below to use traits_type::find to search for it.
127 _M_gcount = 0;
128 sentry __cerb(*this, true);
129 if (__n > 0 && __cerb)
131 ios_base::iostate __err = ios_base::goodbit;
132 __try
134 const char_type __cdelim = traits_type::to_char_type(__delim);
135 const int_type __eof = traits_type::eof();
136 __streambuf_type* __sb = this->rdbuf();
137 int_type __c = __sb->sgetc();
139 bool __large_ignore = false;
140 while (true)
142 while (_M_gcount < __n
143 && !traits_type::eq_int_type(__c, __eof)
144 && !traits_type::eq_int_type(__c, __delim))
146 streamsize __size = std::min(streamsize(__sb->egptr()
147 - __sb->gptr()),
148 streamsize(__n - _M_gcount));
149 if (__size > 1)
151 const char_type* __p = traits_type::find(__sb->gptr(),
152 __size,
153 __cdelim);
154 if (__p)
155 __size = __p - __sb->gptr();
156 __sb->__safe_gbump(__size);
157 _M_gcount += __size;
158 __c = __sb->sgetc();
160 else
162 ++_M_gcount;
163 __c = __sb->snextc();
166 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
167 && !traits_type::eq_int_type(__c, __eof)
168 && !traits_type::eq_int_type(__c, __delim))
170 _M_gcount =
171 __gnu_cxx::__numeric_traits<streamsize>::__min;
172 __large_ignore = true;
174 else
175 break;
178 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max)
180 if (__large_ignore)
181 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
183 if (traits_type::eq_int_type(__c, __eof))
184 __err |= ios_base::eofbit;
185 else
187 if (_M_gcount != __n)
188 ++_M_gcount;
189 __sb->sbumpc();
192 else if (_M_gcount < __n) // implies __c == __delim or EOF
194 if (traits_type::eq_int_type(__c, __eof))
195 __err |= ios_base::eofbit;
196 else
198 ++_M_gcount;
199 __sb->sbumpc();
203 __catch(__cxxabiv1::__forced_unwind&)
205 this->_M_setstate(ios_base::badbit);
206 __throw_exception_again;
208 __catch(...)
209 { this->_M_setstate(ios_base::badbit); }
210 if (__err)
211 this->setstate(__err);
213 return *this;
216 void
217 __istream_extract(istream& __in, char* __s, streamsize __num)
219 typedef basic_istream<char> __istream_type;
220 typedef __istream_type::int_type __int_type;
221 typedef __istream_type::char_type __char_type;
222 typedef __istream_type::traits_type __traits_type;
223 typedef __istream_type::__streambuf_type __streambuf_type;
224 typedef __istream_type::__ctype_type __ctype_type;
226 streamsize __extracted = 0;
227 ios_base::iostate __err = ios_base::goodbit;
228 __istream_type::sentry __cerb(__in, false);
229 if (__cerb)
231 __try
233 // Figure out how many characters to extract.
234 streamsize __width = __in.width();
235 if (0 < __width && __width < __num)
236 __num = __width;
238 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
240 const __int_type __eof = __traits_type::eof();
241 __streambuf_type* __sb = __in.rdbuf();
242 __int_type __c = __sb->sgetc();
244 while (__extracted < __num - 1
245 && !__traits_type::eq_int_type(__c, __eof)
246 && !__ct.is(ctype_base::space,
247 __traits_type::to_char_type(__c)))
249 streamsize __size = std::min(streamsize(__sb->egptr()
250 - __sb->gptr()),
251 streamsize(__num - __extracted
252 - 1));
253 if (__size > 1)
255 __size = (__ct.scan_is(ctype_base::space,
256 __sb->gptr() + 1,
257 __sb->gptr() + __size)
258 - __sb->gptr());
259 __traits_type::copy(__s, __sb->gptr(), __size);
260 __s += __size;
261 __sb->__safe_gbump(__size);
262 __extracted += __size;
263 __c = __sb->sgetc();
265 else
267 *__s++ = __traits_type::to_char_type(__c);
268 ++__extracted;
269 __c = __sb->snextc();
273 if (__extracted < __num - 1
274 && __traits_type::eq_int_type(__c, __eof))
275 __err |= ios_base::eofbit;
277 // _GLIBCXX_RESOLVE_LIB_DEFECTS
278 // 68. Extractors for char* should store null at end
279 *__s = __char_type();
280 __in.width(0);
282 __catch(__cxxabiv1::__forced_unwind&)
284 __in._M_setstate(ios_base::badbit);
285 __throw_exception_again;
287 __catch(...)
288 { __in._M_setstate(ios_base::badbit); }
290 if (!__extracted)
291 __err |= ios_base::failbit;
292 if (__err)
293 __in.setstate(__err);
296 #ifdef _GLIBCXX_USE_WCHAR_T
297 template<>
298 basic_istream<wchar_t>&
299 basic_istream<wchar_t>::
300 getline(char_type* __s, streamsize __n, char_type __delim)
302 _M_gcount = 0;
303 ios_base::iostate __err = ios_base::goodbit;
304 sentry __cerb(*this, true);
305 if (__cerb)
307 __try
309 const int_type __idelim = traits_type::to_int_type(__delim);
310 const int_type __eof = traits_type::eof();
311 __streambuf_type* __sb = this->rdbuf();
312 int_type __c = __sb->sgetc();
314 while (_M_gcount + 1 < __n
315 && !traits_type::eq_int_type(__c, __eof)
316 && !traits_type::eq_int_type(__c, __idelim))
318 streamsize __size = std::min(streamsize(__sb->egptr()
319 - __sb->gptr()),
320 streamsize(__n - _M_gcount
321 - 1));
322 if (__size > 1)
324 const char_type* __p = traits_type::find(__sb->gptr(),
325 __size,
326 __delim);
327 if (__p)
328 __size = __p - __sb->gptr();
329 traits_type::copy(__s, __sb->gptr(), __size);
330 __s += __size;
331 __sb->__safe_gbump(__size);
332 _M_gcount += __size;
333 __c = __sb->sgetc();
335 else
337 *__s++ = traits_type::to_char_type(__c);
338 ++_M_gcount;
339 __c = __sb->snextc();
343 if (traits_type::eq_int_type(__c, __eof))
344 __err |= ios_base::eofbit;
345 else if (traits_type::eq_int_type(__c, __idelim))
347 ++_M_gcount;
348 __sb->sbumpc();
350 else
351 __err |= ios_base::failbit;
353 __catch(__cxxabiv1::__forced_unwind&)
355 this->_M_setstate(ios_base::badbit);
356 __throw_exception_again;
358 __catch(...)
359 { this->_M_setstate(ios_base::badbit); }
361 // _GLIBCXX_RESOLVE_LIB_DEFECTS
362 // 243. get and getline when sentry reports failure.
363 if (__n > 0)
364 *__s = char_type();
365 if (!_M_gcount)
366 __err |= ios_base::failbit;
367 if (__err)
368 this->setstate(__err);
369 return *this;
372 template<>
373 basic_istream<wchar_t>&
374 basic_istream<wchar_t>::
375 ignore(streamsize __n, int_type __delim)
377 if (traits_type::eq_int_type(__delim, traits_type::eof()))
378 return ignore(__n);
380 _M_gcount = 0;
381 sentry __cerb(*this, true);
382 if (__n > 0 && __cerb)
384 ios_base::iostate __err = ios_base::goodbit;
385 __try
387 const char_type __cdelim = traits_type::to_char_type(__delim);
388 const int_type __eof = traits_type::eof();
389 __streambuf_type* __sb = this->rdbuf();
390 int_type __c = __sb->sgetc();
392 bool __large_ignore = false;
393 while (true)
395 while (_M_gcount < __n
396 && !traits_type::eq_int_type(__c, __eof)
397 && !traits_type::eq_int_type(__c, __delim))
399 streamsize __size = std::min(streamsize(__sb->egptr()
400 - __sb->gptr()),
401 streamsize(__n - _M_gcount));
402 if (__size > 1)
404 const char_type* __p = traits_type::find(__sb->gptr(),
405 __size,
406 __cdelim);
407 if (__p)
408 __size = __p - __sb->gptr();
409 __sb->__safe_gbump(__size);
410 _M_gcount += __size;
411 __c = __sb->sgetc();
413 else
415 ++_M_gcount;
416 __c = __sb->snextc();
419 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
420 && !traits_type::eq_int_type(__c, __eof)
421 && !traits_type::eq_int_type(__c, __delim))
423 _M_gcount =
424 __gnu_cxx::__numeric_traits<streamsize>::__min;
425 __large_ignore = true;
427 else
428 break;
431 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max)
433 if (__large_ignore)
434 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
436 if (traits_type::eq_int_type(__c, __eof))
437 __err |= ios_base::eofbit;
438 else
440 if (_M_gcount != __n)
441 ++_M_gcount;
442 __sb->sbumpc();
445 else if (_M_gcount < __n) // implies __c == __delim or EOF
447 if (traits_type::eq_int_type(__c, __eof))
448 __err |= ios_base::eofbit;
449 else
451 ++_M_gcount;
452 __sb->sbumpc();
456 __catch(__cxxabiv1::__forced_unwind&)
458 this->_M_setstate(ios_base::badbit);
459 __throw_exception_again;
461 __catch(...)
462 { this->_M_setstate(ios_base::badbit); }
463 if (__err)
464 this->setstate(__err);
466 return *this;
468 #endif
471 _GLIBCXX_END_NAMESPACE_VERSION
472 } // namespace