libstdc++
vstring.tcc
Go to the documentation of this file.
00001 // Versatile string -*- C++ -*-
00002 
00003 // Copyright (C) 2005-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file ext/vstring.tcc
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{ext/vstring.h}
00028  */
00029 
00030 #ifndef _VSTRING_TCC
00031 #define _VSTRING_TCC 1
00032 
00033 #pragma GCC system_header
00034 
00035 #include <bits/cxxabi_forced.h>
00036 
00037 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00038 {
00039 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00040 
00041   template<typename _CharT, typename _Traits, typename _Alloc,
00042            template <typename, typename, typename> class _Base>
00043     const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00044     __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
00045 
00046   template<typename _CharT, typename _Traits, typename _Alloc,
00047            template <typename, typename, typename> class _Base>
00048     void
00049     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00050     resize(size_type __n, _CharT __c)
00051     {
00052       const size_type __size = this->size();
00053       if (__size < __n)
00054         this->append(__n - __size, __c);
00055       else if (__n < __size)
00056         this->_M_erase(__n, __size - __n);
00057     }
00058 
00059   template<typename _CharT, typename _Traits, typename _Alloc,
00060            template <typename, typename, typename> class _Base>
00061     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00062     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00063     _M_append(const _CharT* __s, size_type __n)
00064     {
00065       const size_type __len = __n + this->size();
00066 
00067       if (__len <= this->capacity() && !this->_M_is_shared())
00068         {
00069           if (__n)
00070             this->_S_copy(this->_M_data() + this->size(), __s, __n);
00071         }
00072       else
00073         this->_M_mutate(this->size(), size_type(0), __s, __n);
00074 
00075       this->_M_set_length(__len);
00076       return *this;
00077     }
00078 
00079   template<typename _CharT, typename _Traits, typename _Alloc,
00080            template <typename, typename, typename> class _Base>
00081     template<typename _InputIterator>
00082       __versa_string<_CharT, _Traits, _Alloc, _Base>&
00083       __versa_string<_CharT, _Traits, _Alloc, _Base>::
00084       _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
00085                           _InputIterator __k1, _InputIterator __k2,
00086                           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 _GLIBCXX_NOEXCEPT
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 _GLIBCXX_NOEXCEPT
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 _GLIBCXX_NOEXCEPT
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 _GLIBCXX_NOEXCEPT
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