vstring.tcc

Go to the documentation of this file.
00001 // Versatile string -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2007 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 2, 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 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /** @file ext/vstring.tcc
00031  *  This file is a GNU extension to the Standard C++ Library.
00032  *  This is an internal header file, included by other library headers.
00033  *  You should not attempt to use it directly.
00034  */
00035 
00036 #ifndef _VSTRING_TCC
00037 #define _VSTRING_TCC 1
00038 
00039 #pragma GCC system_header
00040 
00041 #include <cxxabi-forced.h>
00042 
00043 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00044 
00045   template<typename _CharT, typename _Traits, typename _Alloc,
00046        template <typename, typename, typename> class _Base>
00047     const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00048     __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
00049 
00050   template<typename _CharT, typename _Traits, typename _Alloc,
00051        template <typename, typename, typename> class _Base>
00052     void
00053     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00054     resize(size_type __n, _CharT __c)
00055     {
00056       const size_type __size = this->size();
00057       if (__size < __n)
00058     this->append(__n - __size, __c);
00059       else if (__n < __size)
00060     this->_M_erase(__n, __size - __n);
00061     }
00062 
00063   template<typename _CharT, typename _Traits, typename _Alloc,
00064        template <typename, typename, typename> class _Base>
00065     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00066     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00067     _M_append(const _CharT* __s, size_type __n)
00068     {
00069       const size_type __len = __n + this->size();
00070 
00071       if (__len <= this->capacity() && !this->_M_is_shared())
00072     {
00073       if (__n)
00074         this->_S_copy(this->_M_data() + this->size(), __s, __n);
00075     }
00076       else
00077     this->_M_mutate(this->size(), size_type(0), __s, __n);
00078 
00079       this->_M_set_length(__len);
00080       return *this;
00081     }
00082 
00083   template<typename _CharT, typename _Traits, typename _Alloc,
00084        template <typename, typename, typename> class _Base>
00085     template<typename _InputIterator>
00086       __versa_string<_CharT, _Traits, _Alloc, _Base>&
00087       __versa_string<_CharT, _Traits, _Alloc, _Base>::
00088       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
00089               _InputIterator __k2, std::__false_type)
00090       {
00091     const __versa_string __s(__k1, __k2);
00092     const size_type __n1 = __i2 - __i1;
00093     return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
00094               __s.size());
00095       }
00096 
00097   template<typename _CharT, typename _Traits, typename _Alloc,
00098        template <typename, typename, typename> class _Base>
00099     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00100     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00101     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
00102            _CharT __c)
00103     {
00104       _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
00105 
00106       const size_type __old_size = this->size();
00107       const size_type __new_size = __old_size + __n2 - __n1;
00108 
00109       if (__new_size <= this->capacity() && !this->_M_is_shared())
00110     {
00111       _CharT* __p = this->_M_data() + __pos1;
00112 
00113       const size_type __how_much = __old_size - __pos1 - __n1;
00114       if (__how_much && __n1 != __n2)
00115         this->_S_move(__p + __n2, __p + __n1, __how_much);
00116     }
00117       else
00118     this->_M_mutate(__pos1, __n1, 0, __n2);
00119 
00120       if (__n2)
00121     this->_S_assign(this->_M_data() + __pos1, __n2, __c);
00122 
00123       this->_M_set_length(__new_size);
00124       return *this;
00125     }
00126 
00127   template<typename _CharT, typename _Traits, typename _Alloc,
00128        template <typename, typename, typename> class _Base>
00129     __versa_string<_CharT, _Traits, _Alloc, _Base>&
00130     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00131     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
00132            const size_type __len2)
00133     {
00134       _M_check_length(__len1, __len2, "__versa_string::_M_replace");
00135 
00136       const size_type __old_size = this->size();
00137       const size_type __new_size = __old_size + __len2 - __len1;
00138       
00139       if (__new_size <= this->capacity() && !this->_M_is_shared())
00140     {
00141       _CharT* __p = this->_M_data() + __pos;
00142 
00143       const size_type __how_much = __old_size - __pos - __len1;
00144       if (_M_disjunct(__s))
00145         {
00146           if (__how_much && __len1 != __len2)
00147         this->_S_move(__p + __len2, __p + __len1, __how_much);
00148           if (__len2)
00149         this->_S_copy(__p, __s, __len2);
00150         }
00151       else
00152         {
00153           // Work in-place.
00154           if (__len2 && __len2 <= __len1)
00155         this->_S_move(__p, __s, __len2);
00156           if (__how_much && __len1 != __len2)
00157         this->_S_move(__p + __len2, __p + __len1, __how_much);
00158           if (__len2 > __len1)
00159         {
00160           if (__s + __len2 <= __p + __len1)
00161             this->_S_move(__p, __s, __len2);
00162           else if (__s >= __p + __len1)
00163             this->_S_copy(__p, __s + __len2 - __len1, __len2);
00164           else
00165             {
00166               const size_type __nleft = (__p + __len1) - __s;
00167               this->_S_move(__p, __s, __nleft);
00168               this->_S_copy(__p + __nleft, __p + __len2,
00169                     __len2 - __nleft);
00170             }
00171         }
00172         }
00173     }
00174       else
00175     this->_M_mutate(__pos, __len1, __s, __len2);
00176 
00177       this->_M_set_length(__new_size);
00178       return *this;
00179     }
00180   
00181   template<typename _CharT, typename _Traits, typename _Alloc,
00182        template <typename, typename, typename> class _Base>
00183     __versa_string<_CharT, _Traits, _Alloc, _Base>
00184     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00185           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00186     {
00187       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00188       __str.reserve(__lhs.size() + __rhs.size());
00189       __str.append(__lhs);
00190       __str.append(__rhs);
00191       return __str;
00192     }
00193 
00194   template<typename _CharT, typename _Traits, typename _Alloc,
00195        template <typename, typename, typename> class _Base>
00196     __versa_string<_CharT, _Traits, _Alloc, _Base>
00197     operator+(const _CharT* __lhs,
00198           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00199     {
00200       __glibcxx_requires_string(__lhs);
00201       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
00202       typedef typename __string_type::size_type   __size_type;
00203       const __size_type __len = _Traits::length(__lhs);
00204       __string_type __str;
00205       __str.reserve(__len + __rhs.size());
00206       __str.append(__lhs, __len);
00207       __str.append(__rhs);
00208       return __str;
00209     }
00210 
00211   template<typename _CharT, typename _Traits, typename _Alloc,
00212        template <typename, typename, typename> class _Base>
00213     __versa_string<_CharT, _Traits, _Alloc, _Base>
00214     operator+(_CharT __lhs,
00215           const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
00216     {
00217       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00218       __str.reserve(__rhs.size() + 1);
00219       __str.push_back(__lhs);
00220       __str.append(__rhs);
00221       return __str;
00222     }
00223 
00224   template<typename _CharT, typename _Traits, typename _Alloc,
00225        template <typename, typename, typename> class _Base>
00226     __versa_string<_CharT, _Traits, _Alloc, _Base>
00227     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00228           const _CharT* __rhs)
00229     {
00230       __glibcxx_requires_string(__rhs);
00231       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
00232       typedef typename __string_type::size_type   __size_type;
00233       const __size_type __len = _Traits::length(__rhs);
00234       __string_type __str;
00235       __str.reserve(__lhs.size() + __len);
00236       __str.append(__lhs);
00237       __str.append(__rhs, __len);
00238       return __str;
00239     }
00240 
00241   template<typename _CharT, typename _Traits, typename _Alloc,
00242        template <typename, typename, typename> class _Base>
00243     __versa_string<_CharT, _Traits, _Alloc, _Base>
00244     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
00245           _CharT __rhs)
00246     {
00247       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
00248       __str.reserve(__lhs.size() + 1);
00249       __str.append(__lhs);
00250       __str.push_back(__rhs);
00251       return __str;
00252     }
00253 
00254   template<typename _CharT, typename _Traits, typename _Alloc,
00255        template <typename, typename, typename> class _Base>
00256     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00257     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00258     copy(_CharT* __s, size_type __n, size_type __pos) const
00259     {
00260       _M_check(__pos, "__versa_string::copy");
00261       __n = _M_limit(__pos, __n);
00262       __glibcxx_requires_string_len(__s, __n);
00263       if (__n)
00264     this->_S_copy(__s, this->_M_data() + __pos, __n);
00265       // 21.3.5.7 par 3: do not append null.  (good.)
00266       return __n;
00267     }
00268 
00269   template<typename _CharT, typename _Traits, typename _Alloc,
00270        template <typename, typename, typename> class _Base>
00271     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00272     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00273     find(const _CharT* __s, size_type __pos, size_type __n) const
00274     {
00275       __glibcxx_requires_string_len(__s, __n);
00276       const size_type __size = this->size();
00277       const _CharT* __data = this->_M_data();
00278 
00279       if (__n == 0)
00280     return __pos <= __size ? __pos : npos;
00281 
00282       if (__n <= __size)
00283     {
00284       for (; __pos <= __size - __n; ++__pos)
00285         if (traits_type::eq(__data[__pos], __s[0])
00286         && traits_type::compare(__data + __pos + 1,
00287                     __s + 1, __n - 1) == 0)
00288           return __pos;
00289     }
00290       return npos;
00291     }
00292 
00293   template<typename _CharT, typename _Traits, typename _Alloc,
00294        template <typename, typename, typename> class _Base>
00295     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00296     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00297     find(_CharT __c, size_type __pos) const
00298     {
00299       size_type __ret = npos;
00300       const size_type __size = this->size();
00301       if (__pos < __size)
00302     {
00303       const _CharT* __data = this->_M_data();
00304       const size_type __n = __size - __pos;
00305       const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
00306       if (__p)
00307         __ret = __p - __data;
00308     }
00309       return __ret;
00310     }
00311 
00312   template<typename _CharT, typename _Traits, typename _Alloc,
00313        template <typename, typename, typename> class _Base>
00314     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00315     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00316     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00317     {
00318       __glibcxx_requires_string_len(__s, __n);
00319       const size_type __size = this->size();
00320       if (__n <= __size)
00321     {
00322       __pos = std::min(size_type(__size - __n), __pos);
00323       const _CharT* __data = this->_M_data();
00324       do
00325         {
00326           if (traits_type::compare(__data + __pos, __s, __n) == 0)
00327         return __pos;
00328         }
00329       while (__pos-- > 0);
00330     }
00331       return npos;
00332     }
00333 
00334   template<typename _CharT, typename _Traits, typename _Alloc,
00335        template <typename, typename, typename> class _Base>
00336     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00337     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00338     rfind(_CharT __c, size_type __pos) const
00339     {
00340       size_type __size = this->size();
00341       if (__size)
00342     {
00343       if (--__size > __pos)
00344         __size = __pos;
00345       for (++__size; __size-- > 0; )
00346         if (traits_type::eq(this->_M_data()[__size], __c))
00347           return __size;
00348     }
00349       return npos;
00350     }
00351 
00352   template<typename _CharT, typename _Traits, typename _Alloc,
00353        template <typename, typename, typename> class _Base>
00354     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00355     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00356     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00357     {
00358       __glibcxx_requires_string_len(__s, __n);
00359       for (; __n && __pos < this->size(); ++__pos)
00360     {
00361       const _CharT* __p = traits_type::find(__s, __n,
00362                         this->_M_data()[__pos]);
00363       if (__p)
00364         return __pos;
00365     }
00366       return npos;
00367     }
00368 
00369   template<typename _CharT, typename _Traits, typename _Alloc,
00370        template <typename, typename, typename> class _Base>
00371     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00372     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00373     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00374     {
00375       __glibcxx_requires_string_len(__s, __n);
00376       size_type __size = this->size();
00377       if (__size && __n)
00378     {
00379       if (--__size > __pos)
00380         __size = __pos;
00381       do
00382         {
00383           if (traits_type::find(__s, __n, this->_M_data()[__size]))
00384         return __size;
00385         }
00386       while (__size-- != 0);
00387     }
00388       return npos;
00389     }
00390 
00391   template<typename _CharT, typename _Traits, typename _Alloc,
00392        template <typename, typename, typename> class _Base>
00393     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00394     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00395     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00396     {
00397       __glibcxx_requires_string_len(__s, __n);
00398       for (; __pos < this->size(); ++__pos)
00399     if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
00400       return __pos;
00401       return npos;
00402     }
00403 
00404   template<typename _CharT, typename _Traits, typename _Alloc,
00405        template <typename, typename, typename> class _Base>
00406     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00407     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00408     find_first_not_of(_CharT __c, size_type __pos) const
00409     {
00410       for (; __pos < this->size(); ++__pos)
00411     if (!traits_type::eq(this->_M_data()[__pos], __c))
00412       return __pos;
00413       return npos;
00414     }
00415 
00416   template<typename _CharT, typename _Traits, typename _Alloc,
00417        template <typename, typename, typename> class _Base>
00418     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00419     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00420     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00421     {
00422       __glibcxx_requires_string_len(__s, __n);
00423       size_type __size = this->size();
00424       if (__size)
00425     {
00426       if (--__size > __pos)
00427         __size = __pos;
00428       do
00429         {
00430           if (!traits_type::find(__s, __n, this->_M_data()[__size]))
00431         return __size;
00432         }
00433       while (__size--);
00434     }
00435       return npos;
00436     }
00437 
00438   template<typename _CharT, typename _Traits, typename _Alloc,
00439        template <typename, typename, typename> class _Base>
00440     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
00441     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00442     find_last_not_of(_CharT __c, size_type __pos) const
00443     {
00444       size_type __size = this->size();
00445       if (__size)
00446     {
00447       if (--__size > __pos)
00448         __size = __pos;
00449       do
00450         {
00451           if (!traits_type::eq(this->_M_data()[__size], __c))
00452         return __size;
00453         }
00454       while (__size--);
00455     }
00456       return npos;
00457     }
00458 
00459   template<typename _CharT, typename _Traits, typename _Alloc,
00460        template <typename, typename, typename> class _Base>
00461     int
00462     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00463     compare(size_type __pos, size_type __n, const __versa_string& __str) const
00464     {
00465       _M_check(__pos, "__versa_string::compare");
00466       __n = _M_limit(__pos, __n);
00467       const size_type __osize = __str.size();
00468       const size_type __len = std::min(__n, __osize);
00469       int __r = traits_type::compare(this->_M_data() + __pos,
00470                      __str.data(), __len);
00471       if (!__r)
00472     __r = _S_compare(__n, __osize);
00473       return __r;
00474     }
00475 
00476   template<typename _CharT, typename _Traits, typename _Alloc,
00477        template <typename, typename, typename> class _Base>
00478     int
00479     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00480     compare(size_type __pos1, size_type __n1, const __versa_string& __str,
00481         size_type __pos2, size_type __n2) const
00482     {
00483       _M_check(__pos1, "__versa_string::compare");
00484       __str._M_check(__pos2, "__versa_string::compare");
00485       __n1 = _M_limit(__pos1, __n1);
00486       __n2 = __str._M_limit(__pos2, __n2);
00487       const size_type __len = std::min(__n1, __n2);
00488       int __r = traits_type::compare(this->_M_data() + __pos1,
00489                      __str.data() + __pos2, __len);
00490       if (!__r)
00491     __r = _S_compare(__n1, __n2);
00492       return __r;
00493     }
00494 
00495   template<typename _CharT, typename _Traits, typename _Alloc,
00496        template <typename, typename, typename> class _Base>
00497     int
00498     __versa_string<_CharT, _Traits, _Alloc, _Base>::
00499     compare(const _CharT* __s) const
00500     {
00501       __glibcxx_requires_string(__s);
00502       const size_type __size = this->size();
00503       const size_type __osize = traits_type::length(__s);
00504       const size_type __len = std::min(__size, __osize);
00505       int __r = traits_type::compare(this->_M_data(), __s, __len);
00506       if (!__r)
00507     __r = _S_compare(__size, __osize);
00508       return __r;
00509     }
00510 
00511   template<typename _CharT, typename _Traits, typename _Alloc,
00512        template <typename, typename, typename> class _Base>
00513     int
00514     __versa_string <_CharT, _Traits, _Alloc, _Base>::
00515     compare(size_type __pos, size_type __n1, const _CharT* __s) const
00516     {
00517       __glibcxx_requires_string(__s);
00518       _M_check(__pos, "__versa_string::compare");
00519       __n1 = _M_limit(__pos, __n1);
00520       const size_type __osize = traits_type::length(__s);
00521       const size_type __len = std::min(__n1, __osize);
00522       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
00523       if (!__r)
00524     __r = _S_compare(__n1, __osize);
00525       return __r;
00526     }
00527 
00528   template<typename _CharT, typename _Traits, typename _Alloc,
00529        template <typename, typename, typename> class _Base>
00530     int
00531     __versa_string <_CharT, _Traits, _Alloc, _Base>::
00532     compare(size_type __pos, size_type __n1, const _CharT* __s,
00533         size_type __n2) const
00534     {
00535       __glibcxx_requires_string_len(__s, __n2);
00536       _M_check(__pos, "__versa_string::compare");
00537       __n1 = _M_limit(__pos, __n1);
00538       const size_type __len = std::min(__n1, __n2);
00539       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
00540       if (!__r)
00541     __r = _S_compare(__n1, __n2);
00542       return __r;
00543     }
00544 
00545 _GLIBCXX_END_NAMESPACE
00546 
00547 _GLIBCXX_BEGIN_NAMESPACE(std)
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
00700 
00701 #endif // _VSTRING_TCC

Generated on Wed Mar 26 00:43:33 2008 for libstdc++ by  doxygen 1.5.1