libstdc++
vstring.tcc
Go to the documentation of this file.
00001 // Versatile string -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file ext/vstring.tcc
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{ext/vstring.h}
00029  */
00030 
00031 #ifndef _VSTRING_TCC
00032 #define _VSTRING_TCC 1
00033 
00034 #pragma GCC system_header
00035 
00036 #include <bits/cxxabi_forced.h>
00037 
00038 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00039 {
00040 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00041 
00042   template<typename _CharT, typename _Traits, typename _Alloc,
00043        template <typename, typename, typename> class _Base>
00044     const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00045     __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
00046 
00047   template<typename _CharT, typename _Traits, typename _Alloc,
00048        template <typename, typename, typename> class _Base>
00049     void
00050     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00051     resize(size_type __n, _CharT __c)
00052     {
00053       const size_type __size = this->size();
00054       if (__size < __n)
00055     this->append(__n - __size, __c);
00056       else if (__n < __size)
00057     this->_M_erase(__n, __size - __n);
00058     }
00059 
00060   template<typename _CharT, typename _Traits, typename _Alloc,
00061        template <typename, typename, typename> class _Base>
00062     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00063     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00064     _M_append(const _CharT* __s, size_type __n)
00065     {
00066       const size_type __len = __n + this->size();
00067 
00068       if (__len <= this->capacity() && !this->_M_is_shared())
00069     {
00070       if (__n)
00071         this->_S_copy(this->_M_data() + this->size(), __s, __n);
00072     }
00073       else
00074     this->_M_mutate(this->size(), size_type(0), __s, __n);
00075 
00076       this->_M_set_length(__len);
00077       return *this;
00078     }
00079 
00080   template<typename _CharT, typename _Traits, typename _Alloc,
00081        template <typename, typename, typename> class _Base>
00082     template<typename _InputIterator>
00083       __versa_string<_CharT, _Traits, _Alloc, _Base>&
00084       __versa_string<_CharT, _Traits, _Alloc, _Base>::
00085       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
00086               _InputIterator __k2, std::__false_type)
00087       {
00088     const __versa_string __s(__k1, __k2);
00089     const size_type __n1 = __i2 - __i1;
00090     return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
00091               __s.size());
00092       }
00093 
00094   template<typename _CharT, typename _Traits, typename _Alloc,
00095        template <typename, typename, typename> class _Base>
00096     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00097     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00098     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
00099            _CharT __c)
00100     {
00101       _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
00102 
00103       const size_type __old_size = this->size();
00104       const size_type __new_size = __old_size + __n2 - __n1;
00105 
00106       if (__new_size <= this->capacity() && !this->_M_is_shared())
00107     {
00108       _CharT* __p = this->_M_data() + __pos1;
00109 
00110       const size_type __how_much = __old_size - __pos1 - __n1;
00111       if (__how_much && __n1 != __n2)
00112         this->_S_move(__p + __n2, __p + __n1, __how_much);
00113     }
00114       else
00115     this->_M_mutate(__pos1, __n1, 0, __n2);
00116 
00117       if (__n2)
00118     this->_S_assign(this->_M_data() + __pos1, __n2, __c);
00119 
00120       this->_M_set_length(__new_size);
00121       return *this;
00122     }
00123 
00124   template<typename _CharT, typename _Traits, typename _Alloc,
00125        template <typename, typename, typename> class _Base>
00126     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00127     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00128     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
00129            const size_type __len2)
00130     {
00131       _M_check_length(__len1, __len2, "__versa_string::_M_replace");
00132 
00133       const size_type __old_size = this->size();
00134       const size_type __new_size = __old_size + __len2 - __len1;
00135       
00136       if (__new_size <= this->capacity() && !this->_M_is_shared())
00137     {
00138       _CharT* __p = this->_M_data() + __pos;
00139 
00140       const size_type __how_much = __old_size - __pos - __len1;
00141       if (_M_disjunct(__s))
00142         {
00143           if (__how_much && __len1 != __len2)
00144         this->_S_move(__p + __len2, __p + __len1, __how_much);
00145           if (__len2)
00146         this->_S_copy(__p, __s, __len2);
00147         }
00148       else
00149         {
00150           // Work in-place.
00151           if (__len2 && __len2 <= __len1)
00152         this->_S_move(__p, __s, __len2);
00153           if (__how_much && __len1 != __len2)
00154         this->_S_move(__p + __len2, __p + __len1, __how_much);
00155           if (__len2 > __len1)
00156         {
00157           if (__s + __len2 <= __p + __len1)
00158             this->_S_move(__p, __s, __len2);
00159           else if (__s >= __p + __len1)
00160             this->_S_copy(__p, __s + __len2 - __len1, __len2);
00161           else
00162             {
00163               const size_type __nleft = (__p + __len1) - __s;
00164               this->_S_move(__p, __s, __nleft);
00165               this->_S_copy(__p + __nleft, __p + __len2,
00166                     __len2 - __nleft);
00167             }
00168         }
00169         }
00170     }
00171       else
00172     this->_M_mutate(__pos, __len1, __s, __len2);
00173 
00174       this->_M_set_length(__new_size);
00175       return *this;
00176     }
00177   
00178   template<typename _CharT, typename _Traits, typename _Alloc,
00179        template <typename, typename, typename> class _Base>
00180     __versa_string<_CharT, _Traits, _Alloc, _Base>
00181     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00182           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00183     {
00184       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00185       __str.reserve(__lhs.size() + __rhs.size());
00186       __str.append(__lhs);
00187       __str.append(__rhs);
00188       return __str;
00189     }
00190 
00191   template<typename _CharT, typename _Traits, typename _Alloc,
00192        template <typename, typename, typename> class _Base>
00193     __versa_string<_CharT, _Traits, _Alloc, _Base>
00194     operator+(const _CharT* __lhs,
00195           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00196     {
00197       __glibcxx_requires_string(__lhs);
00198       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
00199       typedef typename __string_type::size_type   __size_type;
00200       const __size_type __len = _Traits::length(__lhs);
00201       __string_type __str;
00202       __str.reserve(__len + __rhs.size());
00203       __str.append(__lhs, __len);
00204       __str.append(__rhs);
00205       return __str;
00206     }
00207 
00208   template<typename _CharT, typename _Traits, typename _Alloc,
00209        template <typename, typename, typename> class _Base>
00210     __versa_string<_CharT, _Traits, _Alloc, _Base>
00211     operator+(_CharT __lhs,
00212           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00213     {
00214       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00215       __str.reserve(__rhs.size() + 1);
00216       __str.push_back(__lhs);
00217       __str.append(__rhs);
00218       return __str;
00219     }
00220 
00221   template<typename _CharT, typename _Traits, typename _Alloc,
00222        template <typename, typename, typename> class _Base>
00223     __versa_string<_CharT, _Traits, _Alloc, _Base>
00224     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00225           const _CharT* __rhs)
00226     {
00227       __glibcxx_requires_string(__rhs);
00228       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
00229       typedef typename __string_type::size_type   __size_type;
00230       const __size_type __len = _Traits::length(__rhs);
00231       __string_type __str;
00232       __str.reserve(__lhs.size() + __len);
00233       __str.append(__lhs);
00234       __str.append(__rhs, __len);
00235       return __str;
00236     }
00237 
00238   template<typename _CharT, typename _Traits, typename _Alloc,
00239        template <typename, typename, typename> class _Base>
00240     __versa_string<_CharT, _Traits, _Alloc, _Base>
00241     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00242           _CharT __rhs)
00243     {
00244       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00245       __str.reserve(__lhs.size() + 1);
00246       __str.append(__lhs);
00247       __str.push_back(__rhs);
00248       return __str;
00249     }
00250 
00251   template<typename _CharT, typename _Traits, typename _Alloc,
00252        template <typename, typename, typename> class _Base>
00253     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00254     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00255     copy(_CharT* __s, size_type __n, size_type __pos) const
00256     {
00257       _M_check(__pos, "__versa_string::copy");
00258       __n = _M_limit(__pos, __n);
00259       __glibcxx_requires_string_len(__s, __n);
00260       if (__n)
00261     this->_S_copy(__s, this->_M_data() + __pos, __n);
00262       // 21.3.5.7 par 3: do not append null.  (good.)
00263       return __n;
00264     }
00265 
00266   template<typename _CharT, typename _Traits, typename _Alloc,
00267        template <typename, typename, typename> class _Base>
00268     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00269     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00270     find(const _CharT* __s, size_type __pos, size_type __n) const
00271     {
00272       __glibcxx_requires_string_len(__s, __n);
00273       const size_type __size = this->size();
00274       const _CharT* __data = this->_M_data();
00275 
00276       if (__n == 0)
00277     return __pos <= __size ? __pos : npos;
00278 
00279       if (__n <= __size)
00280     {
00281       for (; __pos <= __size - __n; ++__pos)
00282         if (traits_type::eq(__data[__pos], __s[0])
00283         && traits_type::compare(__data + __pos + 1,
00284                     __s + 1, __n - 1) == 0)
00285           return __pos;
00286     }
00287       return npos;
00288     }
00289 
00290   template<typename _CharT, typename _Traits, typename _Alloc,
00291        template <typename, typename, typename> class _Base>
00292     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00293     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00294     find(_CharT __c, size_type __pos) const
00295     {
00296       size_type __ret = npos;
00297       const size_type __size = this->size();
00298       if (__pos < __size)
00299     {
00300       const _CharT* __data = this->_M_data();
00301       const size_type __n = __size - __pos;
00302       const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
00303       if (__p)
00304         __ret = __p - __data;
00305     }
00306       return __ret;
00307     }
00308 
00309   template<typename _CharT, typename _Traits, typename _Alloc,
00310        template <typename, typename, typename> class _Base>
00311     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00312     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00313     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00314     {
00315       __glibcxx_requires_string_len(__s, __n);
00316       const size_type __size = this->size();
00317       if (__n <= __size)
00318     {
00319       __pos = std::min(size_type(__size - __n), __pos);
00320       const _CharT* __data = this->_M_data();
00321       do
00322         {
00323           if (traits_type::compare(__data + __pos, __s, __n) == 0)
00324         return __pos;
00325         }
00326       while (__pos-- > 0);
00327     }
00328       return npos;
00329     }
00330 
00331   template<typename _CharT, typename _Traits, typename _Alloc,
00332        template <typename, typename, typename> class _Base>
00333     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00334     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00335     rfind(_CharT __c, size_type __pos) const
00336     {
00337       size_type __size = this->size();
00338       if (__size)
00339     {
00340       if (--__size > __pos)
00341         __size = __pos;
00342       for (++__size; __size-- > 0; )
00343         if (traits_type::eq(this->_M_data()[__size], __c))
00344           return __size;
00345     }
00346       return npos;
00347     }
00348 
00349   template<typename _CharT, typename _Traits, typename _Alloc,
00350        template <typename, typename, typename> class _Base>
00351     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00352     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00353     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00354     {
00355       __glibcxx_requires_string_len(__s, __n);
00356       for (; __n && __pos < this->size(); ++__pos)
00357     {
00358       const _CharT* __p = traits_type::find(__s, __n,
00359                         this->_M_data()[__pos]);
00360       if (__p)
00361         return __pos;
00362     }
00363       return npos;
00364     }
00365 
00366   template<typename _CharT, typename _Traits, typename _Alloc,
00367        template <typename, typename, typename> class _Base>
00368     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00369     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00370     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00371     {
00372       __glibcxx_requires_string_len(__s, __n);
00373       size_type __size = this->size();
00374       if (__size && __n)
00375     {
00376       if (--__size > __pos)
00377         __size = __pos;
00378       do
00379         {
00380           if (traits_type::find(__s, __n, this->_M_data()[__size]))
00381         return __size;
00382         }
00383       while (__size-- != 0);
00384     }
00385       return npos;
00386     }
00387 
00388   template<typename _CharT, typename _Traits, typename _Alloc,
00389        template <typename, typename, typename> class _Base>
00390     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00391     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00392     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00393     {
00394       __glibcxx_requires_string_len(__s, __n);
00395       for (; __pos < this->size(); ++__pos)
00396     if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
00397       return __pos;
00398       return npos;
00399     }
00400 
00401   template<typename _CharT, typename _Traits, typename _Alloc,
00402        template <typename, typename, typename> class _Base>
00403     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00404     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00405     find_first_not_of(_CharT __c, size_type __pos) const
00406     {
00407       for (; __pos < this->size(); ++__pos)
00408     if (!traits_type::eq(this->_M_data()[__pos], __c))
00409       return __pos;
00410       return npos;
00411     }
00412 
00413   template<typename _CharT, typename _Traits, typename _Alloc,
00414        template <typename, typename, typename> class _Base>
00415     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00416     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00417     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00418     {
00419       __glibcxx_requires_string_len(__s, __n);
00420       size_type __size = this->size();
00421       if (__size)
00422     {
00423       if (--__size > __pos)
00424         __size = __pos;
00425       do
00426         {
00427           if (!traits_type::find(__s, __n, this->_M_data()[__size]))
00428         return __size;
00429         }
00430       while (__size--);
00431     }
00432       return npos;
00433     }
00434 
00435   template<typename _CharT, typename _Traits, typename _Alloc,
00436        template <typename, typename, typename> class _Base>
00437     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00438     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00439     find_last_not_of(_CharT __c, size_type __pos) const
00440     {
00441       size_type __size = this->size();
00442       if (__size)
00443     {
00444       if (--__size > __pos)
00445         __size = __pos;
00446       do
00447         {
00448           if (!traits_type::eq(this->_M_data()[__size], __c))
00449         return __size;
00450         }
00451       while (__size--);
00452     }
00453       return npos;
00454     }
00455 
00456   template<typename _CharT, typename _Traits, typename _Alloc,
00457        template <typename, typename, typename> class _Base>
00458     int
00459     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00460     compare(size_type __pos, size_type __n, const __versa_string& __str) const
00461     {
00462       _M_check(__pos, "__versa_string::compare");
00463       __n = _M_limit(__pos, __n);
00464       const size_type __osize = __str.size();
00465       const size_type __len = std::min(__n, __osize);
00466       int __r = traits_type::compare(this->_M_data() + __pos,
00467                      __str.data(), __len);
00468       if (!__r)
00469     __r = this->_S_compare(__n, __osize);
00470       return __r;
00471     }
00472 
00473   template<typename _CharT, typename _Traits, typename _Alloc,
00474        template <typename, typename, typename> class _Base>
00475     int
00476     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00477     compare(size_type __pos1, size_type __n1, const __versa_string& __str,
00478         size_type __pos2, size_type __n2) const
00479     {
00480       _M_check(__pos1, "__versa_string::compare");
00481       __str._M_check(__pos2, "__versa_string::compare");
00482       __n1 = _M_limit(__pos1, __n1);
00483       __n2 = __str._M_limit(__pos2, __n2);
00484       const size_type __len = std::min(__n1, __n2);
00485       int __r = traits_type::compare(this->_M_data() + __pos1,
00486                      __str.data() + __pos2, __len);
00487       if (!__r)
00488     __r = this->_S_compare(__n1, __n2);
00489       return __r;
00490     }
00491 
00492   template<typename _CharT, typename _Traits, typename _Alloc,
00493        template <typename, typename, typename> class _Base>
00494     int
00495     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00496     compare(const _CharT* __s) const
00497     {
00498       __glibcxx_requires_string(__s);
00499       const size_type __size = this->size();
00500       const size_type __osize = traits_type::length(__s);
00501       const size_type __len = std::min(__size, __osize);
00502       int __r = traits_type::compare(this->_M_data(), __s, __len);
00503       if (!__r)
00504     __r = this->_S_compare(__size, __osize);
00505       return __r;
00506     }
00507 
00508   template<typename _CharT, typename _Traits, typename _Alloc,
00509        template <typename, typename, typename> class _Base>
00510     int
00511     __versa_string <_CharT, _Traits, _Alloc, _Base>::
00512     compare(size_type __pos, size_type __n1, const _CharT* __s) const
00513     {
00514       __glibcxx_requires_string(__s);
00515       _M_check(__pos, "__versa_string::compare");
00516       __n1 = _M_limit(__pos, __n1);
00517       const size_type __osize = traits_type::length(__s);
00518       const size_type __len = std::min(__n1, __osize);
00519       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
00520       if (!__r)
00521     __r = this->_S_compare(__n1, __osize);
00522       return __r;
00523     }
00524 
00525   template<typename _CharT, typename _Traits, typename _Alloc,
00526        template <typename, typename, typename> class _Base>
00527     int
00528     __versa_string <_CharT, _Traits, _Alloc, _Base>::
00529     compare(size_type __pos, size_type __n1, const _CharT* __s,
00530         size_type __n2) const
00531     {
00532       __glibcxx_requires_string_len(__s, __n2);
00533       _M_check(__pos, "__versa_string::compare");
00534       __n1 = _M_limit(__pos, __n1);
00535       const size_type __len = std::min(__n1, __n2);
00536       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
00537       if (!__r)
00538     __r = this->_S_compare(__n1, __n2);
00539       return __r;
00540     }
00541 
00542 _GLIBCXX_END_NAMESPACE_VERSION
00543 } // namespace
00544 
00545 namespace std _GLIBCXX_VISIBILITY(default)
00546 {
00547 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00548 
00549   template<typename _CharT, typename _Traits, typename _Alloc,
00550            template <typename, typename, typename> class _Base>
00551     basic_istream<_CharT, _Traits>&
00552     operator>>(basic_istream<_CharT, _Traits>& __in,
00553            __gnu_cxx::__versa_string<_CharT, _Traits,
00554                                      _Alloc, _Base>& __str)
00555     {
00556       typedef basic_istream<_CharT, _Traits>            __istream_type;
00557       typedef typename __istream_type::ios_base         __ios_base;
00558       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
00559                                                     __string_type;
00560       typedef typename __istream_type::int_type     __int_type;
00561       typedef typename __string_type::size_type     __size_type;
00562       typedef ctype<_CharT>             __ctype_type;
00563       typedef typename __ctype_type::ctype_base         __ctype_base;
00564 
00565       __size_type __extracted = 0;
00566       typename __ios_base::iostate __err = __ios_base::goodbit;
00567       typename __istream_type::sentry __cerb(__in, false);
00568       if (__cerb)
00569     {
00570       __try
00571         {
00572           // Avoid reallocation for common case.
00573           __str.erase();
00574           _CharT __buf[128];
00575           __size_type __len = 0;
00576           const streamsize __w = __in.width();
00577           const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
00578                                       : __str.max_size();
00579           const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
00580           const __int_type __eof = _Traits::eof();
00581           __int_type __c = __in.rdbuf()->sgetc();
00582 
00583           while (__extracted < __n
00584              && !_Traits::eq_int_type(__c, __eof)
00585              && !__ct.is(__ctype_base::space,
00586                  _Traits::to_char_type(__c)))
00587         {
00588           if (__len == sizeof(__buf) / sizeof(_CharT))
00589             {
00590               __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
00591               __len = 0;
00592             }
00593           __buf[__len++] = _Traits::to_char_type(__c);
00594           ++__extracted;
00595           __c = __in.rdbuf()->snextc();
00596         }
00597           __str.append(__buf, __len);
00598 
00599           if (_Traits::eq_int_type(__c, __eof))
00600         __err |= __ios_base::eofbit;
00601           __in.width(0);
00602         }
00603       __catch(__cxxabiv1::__forced_unwind&)
00604         {
00605           __in._M_setstate(__ios_base::badbit);
00606           __throw_exception_again;
00607         }
00608       __catch(...)
00609         {
00610           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00611           // 91. Description of operator>> and getline() for string<>
00612           // might cause endless loop
00613           __in._M_setstate(__ios_base::badbit);
00614         }
00615     }
00616       // 211.  operator>>(istream&, string&) doesn't set failbit
00617       if (!__extracted)
00618     __err |= __ios_base::failbit;
00619       if (__err)
00620     __in.setstate(__err);
00621       return __in;
00622     }      
00623 
00624   template<typename _CharT, typename _Traits, typename _Alloc,
00625            template <typename, typename, typename> class _Base>
00626     basic_istream<_CharT, _Traits>&
00627     getline(basic_istream<_CharT, _Traits>& __in,
00628         __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
00629         _CharT __delim)
00630     {
00631       typedef basic_istream<_CharT, _Traits>            __istream_type;
00632       typedef typename __istream_type::ios_base         __ios_base;
00633       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
00634                                                     __string_type;
00635       typedef typename __istream_type::int_type     __int_type;
00636       typedef typename __string_type::size_type     __size_type;
00637 
00638       __size_type __extracted = 0;
00639       const __size_type __n = __str.max_size();
00640       typename __ios_base::iostate __err = __ios_base::goodbit;
00641       typename __istream_type::sentry __cerb(__in, true);
00642       if (__cerb)
00643     {
00644       __try
00645         {
00646           // Avoid reallocation for common case.
00647           __str.erase();
00648           _CharT __buf[128];
00649           __size_type __len = 0;
00650           const __int_type __idelim = _Traits::to_int_type(__delim);
00651           const __int_type __eof = _Traits::eof();
00652           __int_type __c = __in.rdbuf()->sgetc();
00653 
00654           while (__extracted < __n
00655              && !_Traits::eq_int_type(__c, __eof)
00656              && !_Traits::eq_int_type(__c, __idelim))
00657         {
00658           if (__len == sizeof(__buf) / sizeof(_CharT))
00659             {
00660               __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
00661               __len = 0;
00662             }
00663           __buf[__len++] = _Traits::to_char_type(__c);
00664           ++__extracted;
00665           __c = __in.rdbuf()->snextc();
00666         }
00667           __str.append(__buf, __len);
00668 
00669           if (_Traits::eq_int_type(__c, __eof))
00670         __err |= __ios_base::eofbit;
00671           else if (_Traits::eq_int_type(__c, __idelim))
00672         {
00673           ++__extracted;          
00674           __in.rdbuf()->sbumpc();
00675         }
00676           else
00677         __err |= __ios_base::failbit;
00678         }
00679       __catch(__cxxabiv1::__forced_unwind&)
00680         {
00681           __in._M_setstate(__ios_base::badbit);
00682           __throw_exception_again;
00683         }
00684       __catch(...)
00685         {
00686           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00687           // 91. Description of operator>> and getline() for string<>
00688           // might cause endless loop
00689           __in._M_setstate(__ios_base::badbit);
00690         }
00691     }
00692       if (!__extracted)
00693     __err |= __ios_base::failbit;
00694       if (__err)
00695     __in.setstate(__err);
00696       return __in;
00697     }      
00698 
00699 _GLIBCXX_END_NAMESPACE_VERSION
00700 } // namespace
00701 
00702 #endif // _VSTRING_TCC