vstring.tcc

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

Generated on Tue Feb 2 16:57:09 2010 for GNU C++ STL by  doxygen 1.4.7