]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/ext/vstring.tcc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / ext / vstring.tcc
1 // Versatile string -*- C++ -*-
2
3 // Copyright (C) 2005-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.
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 /** @file ext/vstring.tcc
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{ext/vstring.h}
28 */
29
30 #ifndef _VSTRING_TCC
31 #define _VSTRING_TCC 1
32
33 #pragma GCC system_header
34
35 #include <bits/requires_hosted.h> // GNU extensions are currently omitted
36
37 #include <bits/cxxabi_forced.h>
38
39 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
40 {
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
42
43 template<typename _CharT, typename _Traits, typename _Alloc,
44 template <typename, typename, typename> class _Base>
45 const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
46 __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
47
48 template<typename _CharT, typename _Traits, typename _Alloc,
49 template <typename, typename, typename> class _Base>
50 void
51 __versa_string<_CharT, _Traits, _Alloc, _Base>::
52 resize(size_type __n, _CharT __c)
53 {
54 const size_type __size = this->size();
55 if (__size < __n)
56 this->append(__n - __size, __c);
57 else if (__n < __size)
58 this->_M_erase(__n, __size - __n);
59 }
60
61 template<typename _CharT, typename _Traits, typename _Alloc,
62 template <typename, typename, typename> class _Base>
63 __versa_string<_CharT, _Traits, _Alloc, _Base>&
64 __versa_string<_CharT, _Traits, _Alloc, _Base>::
65 _M_append(const _CharT* __s, size_type __n)
66 {
67 const size_type __len = __n + this->size();
68
69 if (__len <= this->capacity() && !this->_M_is_shared())
70 {
71 if (__n)
72 this->_S_copy(this->_M_data() + this->size(), __s, __n);
73 }
74 else
75 this->_M_mutate(this->size(), size_type(0), __s, __n);
76
77 this->_M_set_length(__len);
78 return *this;
79 }
80
81 template<typename _CharT, typename _Traits, typename _Alloc,
82 template <typename, typename, typename> class _Base>
83 template<typename _InputIterator>
84 __versa_string<_CharT, _Traits, _Alloc, _Base>&
85 __versa_string<_CharT, _Traits, _Alloc, _Base>::
86 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
87 _InputIterator __k1, _InputIterator __k2,
88 std::__false_type)
89 {
90 const __versa_string __s(__k1, __k2);
91 const size_type __n1 = __i2 - __i1;
92 return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
93 __s.size());
94 }
95
96 template<typename _CharT, typename _Traits, typename _Alloc,
97 template <typename, typename, typename> class _Base>
98 __versa_string<_CharT, _Traits, _Alloc, _Base>&
99 __versa_string<_CharT, _Traits, _Alloc, _Base>::
100 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
101 _CharT __c)
102 {
103 _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
104
105 const size_type __old_size = this->size();
106 const size_type __new_size = __old_size + __n2 - __n1;
107
108 if (__new_size <= this->capacity() && !this->_M_is_shared())
109 {
110 _CharT* __p = this->_M_data() + __pos1;
111
112 const size_type __how_much = __old_size - __pos1 - __n1;
113 if (__how_much && __n1 != __n2)
114 this->_S_move(__p + __n2, __p + __n1, __how_much);
115 }
116 else
117 this->_M_mutate(__pos1, __n1, 0, __n2);
118
119 if (__n2)
120 this->_S_assign(this->_M_data() + __pos1, __n2, __c);
121
122 this->_M_set_length(__new_size);
123 return *this;
124 }
125
126 template<typename _CharT, typename _Traits, typename _Alloc,
127 template <typename, typename, typename> class _Base>
128 __versa_string<_CharT, _Traits, _Alloc, _Base>&
129 __versa_string<_CharT, _Traits, _Alloc, _Base>::
130 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
131 const size_type __len2)
132 {
133 _M_check_length(__len1, __len2, "__versa_string::_M_replace");
134
135 const size_type __old_size = this->size();
136 const size_type __new_size = __old_size + __len2 - __len1;
137
138 if (__new_size <= this->capacity() && !this->_M_is_shared())
139 {
140 _CharT* __p = this->_M_data() + __pos;
141
142 const size_type __how_much = __old_size - __pos - __len1;
143 if (_M_disjunct(__s))
144 {
145 if (__how_much && __len1 != __len2)
146 this->_S_move(__p + __len2, __p + __len1, __how_much);
147 if (__len2)
148 this->_S_copy(__p, __s, __len2);
149 }
150 else
151 {
152 // Work in-place.
153 if (__len2 && __len2 <= __len1)
154 this->_S_move(__p, __s, __len2);
155 if (__how_much && __len1 != __len2)
156 this->_S_move(__p + __len2, __p + __len1, __how_much);
157 if (__len2 > __len1)
158 {
159 if (__s + __len2 <= __p + __len1)
160 this->_S_move(__p, __s, __len2);
161 else if (__s >= __p + __len1)
162 this->_S_copy(__p, __s + __len2 - __len1, __len2);
163 else
164 {
165 const size_type __nleft = (__p + __len1) - __s;
166 this->_S_move(__p, __s, __nleft);
167 this->_S_copy(__p + __nleft, __p + __len2,
168 __len2 - __nleft);
169 }
170 }
171 }
172 }
173 else
174 this->_M_mutate(__pos, __len1, __s, __len2);
175
176 this->_M_set_length(__new_size);
177 return *this;
178 }
179
180 template<typename _CharT, typename _Traits, typename _Alloc,
181 template <typename, typename, typename> class _Base>
182 __versa_string<_CharT, _Traits, _Alloc, _Base>
183 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
184 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
185 {
186 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
187 __str.reserve(__lhs.size() + __rhs.size());
188 __str.append(__lhs);
189 __str.append(__rhs);
190 return __str;
191 }
192
193 template<typename _CharT, typename _Traits, typename _Alloc,
194 template <typename, typename, typename> class _Base>
195 __versa_string<_CharT, _Traits, _Alloc, _Base>
196 operator+(const _CharT* __lhs,
197 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
198 {
199 __glibcxx_requires_string(__lhs);
200 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
201 typedef typename __string_type::size_type __size_type;
202 const __size_type __len = _Traits::length(__lhs);
203 __string_type __str;
204 __str.reserve(__len + __rhs.size());
205 __str.append(__lhs, __len);
206 __str.append(__rhs);
207 return __str;
208 }
209
210 template<typename _CharT, typename _Traits, typename _Alloc,
211 template <typename, typename, typename> class _Base>
212 __versa_string<_CharT, _Traits, _Alloc, _Base>
213 operator+(_CharT __lhs,
214 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
215 {
216 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
217 __str.reserve(__rhs.size() + 1);
218 __str.push_back(__lhs);
219 __str.append(__rhs);
220 return __str;
221 }
222
223 template<typename _CharT, typename _Traits, typename _Alloc,
224 template <typename, typename, typename> class _Base>
225 __versa_string<_CharT, _Traits, _Alloc, _Base>
226 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
227 const _CharT* __rhs)
228 {
229 __glibcxx_requires_string(__rhs);
230 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
231 typedef typename __string_type::size_type __size_type;
232 const __size_type __len = _Traits::length(__rhs);
233 __string_type __str;
234 __str.reserve(__lhs.size() + __len);
235 __str.append(__lhs);
236 __str.append(__rhs, __len);
237 return __str;
238 }
239
240 template<typename _CharT, typename _Traits, typename _Alloc,
241 template <typename, typename, typename> class _Base>
242 __versa_string<_CharT, _Traits, _Alloc, _Base>
243 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
244 _CharT __rhs)
245 {
246 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
247 __str.reserve(__lhs.size() + 1);
248 __str.append(__lhs);
249 __str.push_back(__rhs);
250 return __str;
251 }
252
253 template<typename _CharT, typename _Traits, typename _Alloc,
254 template <typename, typename, typename> class _Base>
255 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
256 __versa_string<_CharT, _Traits, _Alloc, _Base>::
257 copy(_CharT* __s, size_type __n, size_type __pos) const
258 {
259 _M_check(__pos, "__versa_string::copy");
260 __n = _M_limit(__pos, __n);
261 __glibcxx_requires_string_len(__s, __n);
262 if (__n)
263 this->_S_copy(__s, this->_M_data() + __pos, __n);
264 // 21.3.5.7 par 3: do not append null. (good.)
265 return __n;
266 }
267
268 template<typename _CharT, typename _Traits, typename _Alloc,
269 template <typename, typename, typename> class _Base>
270 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
271 __versa_string<_CharT, _Traits, _Alloc, _Base>::
272 find(const _CharT* __s, size_type __pos, size_type __n) const
273 {
274 __glibcxx_requires_string_len(__s, __n);
275 const size_type __size = this->size();
276 const _CharT* __data = this->_M_data();
277
278 if (__n == 0)
279 return __pos <= __size ? __pos : npos;
280
281 if (__n <= __size)
282 {
283 for (; __pos <= __size - __n; ++__pos)
284 if (traits_type::eq(__data[__pos], __s[0])
285 && traits_type::compare(__data + __pos + 1,
286 __s + 1, __n - 1) == 0)
287 return __pos;
288 }
289 return npos;
290 }
291
292 template<typename _CharT, typename _Traits, typename _Alloc,
293 template <typename, typename, typename> class _Base>
294 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
295 __versa_string<_CharT, _Traits, _Alloc, _Base>::
296 find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
297 {
298 size_type __ret = npos;
299 const size_type __size = this->size();
300 if (__pos < __size)
301 {
302 const _CharT* __data = this->_M_data();
303 const size_type __n = __size - __pos;
304 const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
305 if (__p)
306 __ret = __p - __data;
307 }
308 return __ret;
309 }
310
311 template<typename _CharT, typename _Traits, typename _Alloc,
312 template <typename, typename, typename> class _Base>
313 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
314 __versa_string<_CharT, _Traits, _Alloc, _Base>::
315 rfind(const _CharT* __s, size_type __pos, size_type __n) const
316 {
317 __glibcxx_requires_string_len(__s, __n);
318 const size_type __size = this->size();
319 if (__n <= __size)
320 {
321 __pos = std::min(size_type(__size - __n), __pos);
322 const _CharT* __data = this->_M_data();
323 do
324 {
325 if (traits_type::compare(__data + __pos, __s, __n) == 0)
326 return __pos;
327 }
328 while (__pos-- > 0);
329 }
330 return npos;
331 }
332
333 template<typename _CharT, typename _Traits, typename _Alloc,
334 template <typename, typename, typename> class _Base>
335 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
336 __versa_string<_CharT, _Traits, _Alloc, _Base>::
337 rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
338 {
339 size_type __size = this->size();
340 if (__size)
341 {
342 if (--__size > __pos)
343 __size = __pos;
344 for (++__size; __size-- > 0; )
345 if (traits_type::eq(this->_M_data()[__size], __c))
346 return __size;
347 }
348 return npos;
349 }
350
351 template<typename _CharT, typename _Traits, typename _Alloc,
352 template <typename, typename, typename> class _Base>
353 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
354 __versa_string<_CharT, _Traits, _Alloc, _Base>::
355 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
356 {
357 __glibcxx_requires_string_len(__s, __n);
358 for (; __n && __pos < this->size(); ++__pos)
359 {
360 const _CharT* __p = traits_type::find(__s, __n,
361 this->_M_data()[__pos]);
362 if (__p)
363 return __pos;
364 }
365 return npos;
366 }
367
368 template<typename _CharT, typename _Traits, typename _Alloc,
369 template <typename, typename, typename> class _Base>
370 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
371 __versa_string<_CharT, _Traits, _Alloc, _Base>::
372 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
373 {
374 __glibcxx_requires_string_len(__s, __n);
375 size_type __size = this->size();
376 if (__size && __n)
377 {
378 if (--__size > __pos)
379 __size = __pos;
380 do
381 {
382 if (traits_type::find(__s, __n, this->_M_data()[__size]))
383 return __size;
384 }
385 while (__size-- != 0);
386 }
387 return npos;
388 }
389
390 template<typename _CharT, typename _Traits, typename _Alloc,
391 template <typename, typename, typename> class _Base>
392 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
393 __versa_string<_CharT, _Traits, _Alloc, _Base>::
394 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
395 {
396 __glibcxx_requires_string_len(__s, __n);
397 for (; __pos < this->size(); ++__pos)
398 if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
399 return __pos;
400 return npos;
401 }
402
403 template<typename _CharT, typename _Traits, typename _Alloc,
404 template <typename, typename, typename> class _Base>
405 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
406 __versa_string<_CharT, _Traits, _Alloc, _Base>::
407 find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
408 {
409 for (; __pos < this->size(); ++__pos)
410 if (!traits_type::eq(this->_M_data()[__pos], __c))
411 return __pos;
412 return npos;
413 }
414
415 template<typename _CharT, typename _Traits, typename _Alloc,
416 template <typename, typename, typename> class _Base>
417 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
418 __versa_string<_CharT, _Traits, _Alloc, _Base>::
419 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
420 {
421 __glibcxx_requires_string_len(__s, __n);
422 size_type __size = this->size();
423 if (__size)
424 {
425 if (--__size > __pos)
426 __size = __pos;
427 do
428 {
429 if (!traits_type::find(__s, __n, this->_M_data()[__size]))
430 return __size;
431 }
432 while (__size--);
433 }
434 return npos;
435 }
436
437 template<typename _CharT, typename _Traits, typename _Alloc,
438 template <typename, typename, typename> class _Base>
439 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
440 __versa_string<_CharT, _Traits, _Alloc, _Base>::
441 find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
442 {
443 size_type __size = this->size();
444 if (__size)
445 {
446 if (--__size > __pos)
447 __size = __pos;
448 do
449 {
450 if (!traits_type::eq(this->_M_data()[__size], __c))
451 return __size;
452 }
453 while (__size--);
454 }
455 return npos;
456 }
457
458 template<typename _CharT, typename _Traits, typename _Alloc,
459 template <typename, typename, typename> class _Base>
460 int
461 __versa_string<_CharT, _Traits, _Alloc, _Base>::
462 compare(size_type __pos, size_type __n, const __versa_string& __str) const
463 {
464 _M_check(__pos, "__versa_string::compare");
465 __n = _M_limit(__pos, __n);
466 const size_type __osize = __str.size();
467 const size_type __len = std::min(__n, __osize);
468 int __r = traits_type::compare(this->_M_data() + __pos,
469 __str.data(), __len);
470 if (!__r)
471 __r = this->_S_compare(__n, __osize);
472 return __r;
473 }
474
475 template<typename _CharT, typename _Traits, typename _Alloc,
476 template <typename, typename, typename> class _Base>
477 int
478 __versa_string<_CharT, _Traits, _Alloc, _Base>::
479 compare(size_type __pos1, size_type __n1, const __versa_string& __str,
480 size_type __pos2, size_type __n2) const
481 {
482 _M_check(__pos1, "__versa_string::compare");
483 __str._M_check(__pos2, "__versa_string::compare");
484 __n1 = _M_limit(__pos1, __n1);
485 __n2 = __str._M_limit(__pos2, __n2);
486 const size_type __len = std::min(__n1, __n2);
487 int __r = traits_type::compare(this->_M_data() + __pos1,
488 __str.data() + __pos2, __len);
489 if (!__r)
490 __r = this->_S_compare(__n1, __n2);
491 return __r;
492 }
493
494 template<typename _CharT, typename _Traits, typename _Alloc,
495 template <typename, typename, typename> class _Base>
496 int
497 __versa_string<_CharT, _Traits, _Alloc, _Base>::
498 compare(const _CharT* __s) const
499 {
500 __glibcxx_requires_string(__s);
501 const size_type __size = this->size();
502 const size_type __osize = traits_type::length(__s);
503 const size_type __len = std::min(__size, __osize);
504 int __r = traits_type::compare(this->_M_data(), __s, __len);
505 if (!__r)
506 __r = this->_S_compare(__size, __osize);
507 return __r;
508 }
509
510 template<typename _CharT, typename _Traits, typename _Alloc,
511 template <typename, typename, typename> class _Base>
512 int
513 __versa_string <_CharT, _Traits, _Alloc, _Base>::
514 compare(size_type __pos, size_type __n1, const _CharT* __s) const
515 {
516 __glibcxx_requires_string(__s);
517 _M_check(__pos, "__versa_string::compare");
518 __n1 = _M_limit(__pos, __n1);
519 const size_type __osize = traits_type::length(__s);
520 const size_type __len = std::min(__n1, __osize);
521 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
522 if (!__r)
523 __r = this->_S_compare(__n1, __osize);
524 return __r;
525 }
526
527 template<typename _CharT, typename _Traits, typename _Alloc,
528 template <typename, typename, typename> class _Base>
529 int
530 __versa_string <_CharT, _Traits, _Alloc, _Base>::
531 compare(size_type __pos, size_type __n1, const _CharT* __s,
532 size_type __n2) const
533 {
534 __glibcxx_requires_string_len(__s, __n2);
535 _M_check(__pos, "__versa_string::compare");
536 __n1 = _M_limit(__pos, __n1);
537 const size_type __len = std::min(__n1, __n2);
538 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
539 if (!__r)
540 __r = this->_S_compare(__n1, __n2);
541 return __r;
542 }
543
544 _GLIBCXX_END_NAMESPACE_VERSION
545 } // namespace
546
547 namespace std _GLIBCXX_VISIBILITY(default)
548 {
549 _GLIBCXX_BEGIN_NAMESPACE_VERSION
550
551 template<typename _CharT, typename _Traits, typename _Alloc,
552 template <typename, typename, typename> class _Base>
553 basic_istream<_CharT, _Traits>&
554 operator>>(basic_istream<_CharT, _Traits>& __in,
555 __gnu_cxx::__versa_string<_CharT, _Traits,
556 _Alloc, _Base>& __str)
557 {
558 typedef basic_istream<_CharT, _Traits> __istream_type;
559 typedef typename __istream_type::ios_base __ios_base;
560 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
561 __string_type;
562 typedef typename __istream_type::int_type __int_type;
563 typedef typename __string_type::size_type __size_type;
564 typedef ctype<_CharT> __ctype_type;
565 typedef typename __ctype_type::ctype_base __ctype_base;
566
567 __size_type __extracted = 0;
568 typename __ios_base::iostate __err = __ios_base::goodbit;
569 typename __istream_type::sentry __cerb(__in, false);
570 if (__cerb)
571 {
572 __try
573 {
574 // Avoid reallocation for common case.
575 __str.erase();
576 _CharT __buf[128];
577 __size_type __len = 0;
578 const streamsize __w = __in.width();
579 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
580 : __str.max_size();
581 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
582 const __int_type __eof = _Traits::eof();
583 __int_type __c = __in.rdbuf()->sgetc();
584
585 while (__extracted < __n
586 && !_Traits::eq_int_type(__c, __eof)
587 && !__ct.is(__ctype_base::space,
588 _Traits::to_char_type(__c)))
589 {
590 if (__len == sizeof(__buf) / sizeof(_CharT))
591 {
592 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
593 __len = 0;
594 }
595 __buf[__len++] = _Traits::to_char_type(__c);
596 ++__extracted;
597 __c = __in.rdbuf()->snextc();
598 }
599 __str.append(__buf, __len);
600
601 if (_Traits::eq_int_type(__c, __eof))
602 __err |= __ios_base::eofbit;
603 __in.width(0);
604 }
605 __catch(__cxxabiv1::__forced_unwind&)
606 {
607 __in._M_setstate(__ios_base::badbit);
608 __throw_exception_again;
609 }
610 __catch(...)
611 {
612 // _GLIBCXX_RESOLVE_LIB_DEFECTS
613 // 91. Description of operator>> and getline() for string<>
614 // might cause endless loop
615 __in._M_setstate(__ios_base::badbit);
616 }
617 }
618 // 211. operator>>(istream&, string&) doesn't set failbit
619 if (!__extracted)
620 __err |= __ios_base::failbit;
621 if (__err)
622 __in.setstate(__err);
623 return __in;
624 }
625
626 template<typename _CharT, typename _Traits, typename _Alloc,
627 template <typename, typename, typename> class _Base>
628 basic_istream<_CharT, _Traits>&
629 getline(basic_istream<_CharT, _Traits>& __in,
630 __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
631 _CharT __delim)
632 {
633 typedef basic_istream<_CharT, _Traits> __istream_type;
634 typedef typename __istream_type::ios_base __ios_base;
635 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
636 __string_type;
637 typedef typename __istream_type::int_type __int_type;
638 typedef typename __string_type::size_type __size_type;
639
640 __size_type __extracted = 0;
641 const __size_type __n = __str.max_size();
642 typename __ios_base::iostate __err = __ios_base::goodbit;
643 typename __istream_type::sentry __cerb(__in, true);
644 if (__cerb)
645 {
646 __try
647 {
648 // Avoid reallocation for common case.
649 __str.erase();
650 _CharT __buf[128];
651 __size_type __len = 0;
652 const __int_type __idelim = _Traits::to_int_type(__delim);
653 const __int_type __eof = _Traits::eof();
654 __int_type __c = __in.rdbuf()->sgetc();
655
656 while (__extracted < __n
657 && !_Traits::eq_int_type(__c, __eof)
658 && !_Traits::eq_int_type(__c, __idelim))
659 {
660 if (__len == sizeof(__buf) / sizeof(_CharT))
661 {
662 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
663 __len = 0;
664 }
665 __buf[__len++] = _Traits::to_char_type(__c);
666 ++__extracted;
667 __c = __in.rdbuf()->snextc();
668 }
669 __str.append(__buf, __len);
670
671 if (_Traits::eq_int_type(__c, __eof))
672 __err |= __ios_base::eofbit;
673 else if (_Traits::eq_int_type(__c, __idelim))
674 {
675 ++__extracted;
676 __in.rdbuf()->sbumpc();
677 }
678 else
679 __err |= __ios_base::failbit;
680 }
681 __catch(__cxxabiv1::__forced_unwind&)
682 {
683 __in._M_setstate(__ios_base::badbit);
684 __throw_exception_again;
685 }
686 __catch(...)
687 {
688 // _GLIBCXX_RESOLVE_LIB_DEFECTS
689 // 91. Description of operator>> and getline() for string<>
690 // might cause endless loop
691 __in._M_setstate(__ios_base::badbit);
692 }
693 }
694 if (!__extracted)
695 __err |= __ios_base::failbit;
696 if (__err)
697 __in.setstate(__err);
698 return __in;
699 }
700
701 _GLIBCXX_END_NAMESPACE_VERSION
702 } // namespace
703
704 #endif // _VSTRING_TCC