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