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