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