# vstring.tcc

Go to the documentation of this file.

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