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