gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / libstdc++-v3 / src / c++98 / istream-string.cc
1 // Input streams operating on strings-*- C++ -*-
2
3 // Copyright (C) 2004-2015 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.
10
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.
15
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.
19
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/>.
24
25 //
26 // ISO C++ 14882: 27.6.1  Input streams
27 //
28
29 #ifndef _GLIBCXX_USE_CXX11_ABI
30 // Instantiations in this file use the new SSO std::string ABI unless included
31 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
32 # define _GLIBCXX_USE_CXX11_ABI 1
33 #endif
34 #include <istream>
35 #include <string>
36
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
40
41   template<>
42     basic_istream<char>&
43     operator>>(basic_istream<char>& __in, basic_string<char>& __str)
44     {
45       typedef basic_istream<char>               __istream_type;
46       typedef __istream_type::int_type          __int_type;
47       typedef __istream_type::traits_type       __traits_type;
48       typedef __istream_type::__streambuf_type  __streambuf_type;
49       typedef __istream_type::__ctype_type      __ctype_type;
50       typedef basic_string<char>                __string_type;
51       typedef __string_type::size_type          __size_type;
52
53       __size_type __extracted = 0;
54       ios_base::iostate __err = ios_base::goodbit;
55       __istream_type::sentry __cerb(__in, false);
56       if (__cerb)
57         {
58           __try
59             {
60               __str.erase();
61               const streamsize __w = __in.width();
62               const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
63                                               : __str.max_size();
64               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
65               const __int_type __eof = __traits_type::eof();
66               __streambuf_type* __sb = __in.rdbuf();
67               __int_type __c = __sb->sgetc();
68
69               while (__extracted < __n
70                      && !__traits_type::eq_int_type(__c, __eof)
71                      && !__ct.is(ctype_base::space,
72                                  __traits_type::to_char_type(__c)))
73                 {
74                   streamsize __size = std::min(streamsize(__sb->egptr()
75                                                           - __sb->gptr()),
76                                                streamsize(__n - __extracted));
77                   if (__size > 1)
78                     {
79                       __size = (__ct.scan_is(ctype_base::space,
80                                              __sb->gptr() + 1,
81                                              __sb->gptr() + __size)
82                                 - __sb->gptr());
83                       __str.append(__sb->gptr(), __size);
84                       __sb->__safe_gbump(__size);
85                       __extracted += __size;
86                       __c = __sb->sgetc();
87                     }
88                   else
89                     {
90                       __str += __traits_type::to_char_type(__c);
91                       ++__extracted;
92                       __c = __sb->snextc();
93                     }
94                 }
95
96               if (__traits_type::eq_int_type(__c, __eof))
97                 __err |= ios_base::eofbit;
98               __in.width(0);
99             }
100           __catch(__cxxabiv1::__forced_unwind&)
101             {
102               __in._M_setstate(ios_base::badbit);
103               __throw_exception_again;
104             }
105           __catch(...)
106             {
107               // _GLIBCXX_RESOLVE_LIB_DEFECTS
108               // 91. Description of operator>> and getline() for string<>
109               // might cause endless loop
110               __in._M_setstate(ios_base::badbit);
111             }
112         }
113       if (!__extracted)
114         __err |= ios_base::failbit;
115       if (__err)
116         __in.setstate(__err);
117       return __in;
118     }
119
120   template<>
121     basic_istream<char>&
122     getline(basic_istream<char>& __in, basic_string<char>& __str,
123             char __delim)
124     {
125       typedef basic_istream<char>               __istream_type;
126       typedef __istream_type::int_type          __int_type;
127       typedef __istream_type::char_type         __char_type;
128       typedef __istream_type::traits_type       __traits_type;
129       typedef __istream_type::__streambuf_type  __streambuf_type;
130       typedef basic_string<char>                __string_type;
131       typedef __string_type::size_type          __size_type;
132
133       __size_type __extracted = 0;
134       const __size_type __n = __str.max_size();
135       ios_base::iostate __err = ios_base::goodbit;
136       __istream_type::sentry __cerb(__in, true);
137       if (__cerb)
138         {
139           __try
140             {
141               __str.erase();
142               const __int_type __idelim = __traits_type::to_int_type(__delim);
143               const __int_type __eof = __traits_type::eof();
144               __streambuf_type* __sb = __in.rdbuf();
145               __int_type __c = __sb->sgetc();
146
147               while (__extracted < __n
148                      && !__traits_type::eq_int_type(__c, __eof)
149                      && !__traits_type::eq_int_type(__c, __idelim))
150                 {
151                   streamsize __size = std::min(streamsize(__sb->egptr()
152                                                           - __sb->gptr()),
153                                                streamsize(__n - __extracted));
154                   if (__size > 1)
155                     {
156                       const __char_type* __p = __traits_type::find(__sb->gptr(),
157                                                                    __size,
158                                                                    __delim);
159                       if (__p)
160                         __size = __p - __sb->gptr();
161                       __str.append(__sb->gptr(), __size);
162                       __sb->__safe_gbump(__size);
163                       __extracted += __size;
164                       __c = __sb->sgetc();
165                     }
166                   else
167                     {
168                       __str += __traits_type::to_char_type(__c);
169                       ++__extracted;
170                       __c = __sb->snextc();
171                     }
172                 }
173
174               if (__traits_type::eq_int_type(__c, __eof))
175                 __err |= ios_base::eofbit;
176               else if (__traits_type::eq_int_type(__c, __idelim))
177                 {
178                   ++__extracted;
179                   __sb->sbumpc();
180                 }
181               else
182                 __err |= ios_base::failbit;
183             }
184           __catch(__cxxabiv1::__forced_unwind&)
185             {
186               __in._M_setstate(ios_base::badbit);
187               __throw_exception_again;
188             }
189           __catch(...)
190             {
191               // _GLIBCXX_RESOLVE_LIB_DEFECTS
192               // 91. Description of operator>> and getline() for string<>
193               // might cause endless loop
194               __in._M_setstate(ios_base::badbit);
195             }
196         }
197       if (!__extracted)
198         __err |= ios_base::failbit;
199       if (__err)
200         __in.setstate(__err);
201       return __in;
202     }
203
204 #ifdef _GLIBCXX_USE_WCHAR_T
205   template<>
206     basic_istream<wchar_t>&
207     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
208             wchar_t __delim)
209     {
210       typedef basic_istream<wchar_t>            __istream_type;
211       typedef __istream_type::int_type          __int_type;
212       typedef __istream_type::char_type         __char_type;
213       typedef __istream_type::traits_type       __traits_type;
214       typedef __istream_type::__streambuf_type  __streambuf_type;
215       typedef basic_string<wchar_t>             __string_type;
216       typedef __string_type::size_type          __size_type;
217
218       __size_type __extracted = 0;
219       const __size_type __n = __str.max_size();
220       ios_base::iostate __err = ios_base::goodbit;
221       __istream_type::sentry __cerb(__in, true);
222       if (__cerb)
223         {
224           __try
225             {
226               __str.erase();
227               const __int_type __idelim = __traits_type::to_int_type(__delim);
228               const __int_type __eof = __traits_type::eof();
229               __streambuf_type* __sb = __in.rdbuf();
230               __int_type __c = __sb->sgetc();
231
232               while (__extracted < __n
233                      && !__traits_type::eq_int_type(__c, __eof)
234                      && !__traits_type::eq_int_type(__c, __idelim))
235                 {
236                   streamsize __size = std::min(streamsize(__sb->egptr()
237                                                           - __sb->gptr()),
238                                                streamsize(__n - __extracted));
239                   if (__size > 1)
240                     {
241                       const __char_type* __p = __traits_type::find(__sb->gptr(),
242                                                                    __size,
243                                                                    __delim);
244                       if (__p)
245                         __size = __p - __sb->gptr();
246                       __str.append(__sb->gptr(), __size);
247                       __sb->__safe_gbump(__size);
248                       __extracted += __size;
249                       __c = __sb->sgetc();
250                     }
251                   else
252                     {
253                       __str += __traits_type::to_char_type(__c);
254                       ++__extracted;
255                       __c = __sb->snextc();
256                     }
257                 }
258
259               if (__traits_type::eq_int_type(__c, __eof))
260                 __err |= ios_base::eofbit;
261               else if (__traits_type::eq_int_type(__c, __idelim))
262                 {
263                   ++__extracted;
264                   __sb->sbumpc();
265                 }
266               else
267                 __err |= ios_base::failbit;
268             }
269           __catch(__cxxabiv1::__forced_unwind&)
270             {
271               __in._M_setstate(ios_base::badbit);
272               __throw_exception_again;
273             }
274           __catch(...)
275             {
276               // _GLIBCXX_RESOLVE_LIB_DEFECTS
277               // 91. Description of operator>> and getline() for string<>
278               // might cause endless loop
279               __in._M_setstate(ios_base::badbit);
280             }
281         }
282       if (!__extracted)
283         __err |= ios_base::failbit;
284       if (__err)
285         __in.setstate(__err);
286       return __in;
287     }
288 #endif
289
290 _GLIBCXX_END_NAMESPACE_VERSION
291 } // namespace