1*f8a1b7d9SAlexander Kabaev // Versatile string -*- C++ -*-
2*f8a1b7d9SAlexander Kabaev 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
4*f8a1b7d9SAlexander Kabaev //
5*f8a1b7d9SAlexander Kabaev // This file is part of the GNU ISO C++ Library.  This library is free
6*f8a1b7d9SAlexander Kabaev // software; you can redistribute it and/or modify it under the
7*f8a1b7d9SAlexander Kabaev // terms of the GNU General Public License as published by the
8*f8a1b7d9SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option)
9*f8a1b7d9SAlexander Kabaev // any later version.
10*f8a1b7d9SAlexander Kabaev 
11*f8a1b7d9SAlexander Kabaev // This library is distributed in the hope that it will be useful,
12*f8a1b7d9SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*f8a1b7d9SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*f8a1b7d9SAlexander Kabaev // GNU General Public License for more details.
15*f8a1b7d9SAlexander Kabaev 
16*f8a1b7d9SAlexander Kabaev // You should have received a copy of the GNU General Public License along
17*f8a1b7d9SAlexander Kabaev // with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*f8a1b7d9SAlexander Kabaev // USA.
20*f8a1b7d9SAlexander Kabaev 
21*f8a1b7d9SAlexander Kabaev // As a special exception, you may use this file as part of a free software
22*f8a1b7d9SAlexander Kabaev // library without restriction.  Specifically, if other files instantiate
23*f8a1b7d9SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile
24*f8a1b7d9SAlexander Kabaev // this file and link it with other files to produce an executable, this
25*f8a1b7d9SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by
26*f8a1b7d9SAlexander Kabaev // the GNU General Public License.  This exception does not however
27*f8a1b7d9SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by
28*f8a1b7d9SAlexander Kabaev // the GNU General Public License.
29*f8a1b7d9SAlexander Kabaev 
30*f8a1b7d9SAlexander Kabaev /** @file ext/vstring.tcc
31*f8a1b7d9SAlexander Kabaev  *  This file is a GNU extension to the Standard C++ Library.
32*f8a1b7d9SAlexander Kabaev  *  This is an internal header file, included by other library headers.
33*f8a1b7d9SAlexander Kabaev  *  You should not attempt to use it directly.
34*f8a1b7d9SAlexander Kabaev  */
35*f8a1b7d9SAlexander Kabaev 
36*f8a1b7d9SAlexander Kabaev #ifndef _VSTRING_TCC
37*f8a1b7d9SAlexander Kabaev #define _VSTRING_TCC 1
38*f8a1b7d9SAlexander Kabaev 
39*f8a1b7d9SAlexander Kabaev #pragma GCC system_header
40*f8a1b7d9SAlexander Kabaev 
41*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
42*f8a1b7d9SAlexander Kabaev 
43*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
44*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
45*f8a1b7d9SAlexander Kabaev     const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
46*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
47*f8a1b7d9SAlexander Kabaev 
48*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
49*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
50*f8a1b7d9SAlexander Kabaev     void
51*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
resize(size_type __n,_CharT __c)52*f8a1b7d9SAlexander Kabaev     resize(size_type __n, _CharT __c)
53*f8a1b7d9SAlexander Kabaev     {
54*f8a1b7d9SAlexander Kabaev       const size_type __size = this->size();
55*f8a1b7d9SAlexander Kabaev       if (__size < __n)
56*f8a1b7d9SAlexander Kabaev 	this->append(__n - __size, __c);
57*f8a1b7d9SAlexander Kabaev       else if (__n < __size)
58*f8a1b7d9SAlexander Kabaev 	this->_M_erase(__n, __size - __n);
59*f8a1b7d9SAlexander Kabaev     }
60*f8a1b7d9SAlexander Kabaev 
61*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
62*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
63*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>&
64*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
_M_append(const _CharT * __s,size_type __n)65*f8a1b7d9SAlexander Kabaev     _M_append(const _CharT* __s, size_type __n)
66*f8a1b7d9SAlexander Kabaev     {
67*f8a1b7d9SAlexander Kabaev       const size_type __len = __n + this->size();
68*f8a1b7d9SAlexander Kabaev 
69*f8a1b7d9SAlexander Kabaev       if (__len <= this->capacity() && !this->_M_is_shared())
70*f8a1b7d9SAlexander Kabaev 	{
71*f8a1b7d9SAlexander Kabaev 	  if (__n)
72*f8a1b7d9SAlexander Kabaev 	    this->_S_copy(this->_M_data() + this->size(), __s, __n);
73*f8a1b7d9SAlexander Kabaev 	}
74*f8a1b7d9SAlexander Kabaev       else
75*f8a1b7d9SAlexander Kabaev 	this->_M_mutate(this->size(), size_type(0), __s, __n);
76*f8a1b7d9SAlexander Kabaev 
77*f8a1b7d9SAlexander Kabaev       this->_M_set_length(__len);
78*f8a1b7d9SAlexander Kabaev       return *this;
79*f8a1b7d9SAlexander Kabaev     }
80*f8a1b7d9SAlexander Kabaev 
81*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
82*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
83*f8a1b7d9SAlexander Kabaev     template<typename _InputIterator>
84*f8a1b7d9SAlexander Kabaev       __versa_string<_CharT, _Traits, _Alloc, _Base>&
85*f8a1b7d9SAlexander Kabaev       __versa_string<_CharT, _Traits, _Alloc, _Base>::
_M_replace_dispatch(iterator __i1,iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)86*f8a1b7d9SAlexander Kabaev       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
87*f8a1b7d9SAlexander Kabaev 			  _InputIterator __k2, std::__false_type)
88*f8a1b7d9SAlexander Kabaev       {
89*f8a1b7d9SAlexander Kabaev 	const __versa_string __s(__k1, __k2);
90*f8a1b7d9SAlexander Kabaev 	const size_type __n1 = __i2 - __i1;
91*f8a1b7d9SAlexander Kabaev 	return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
92*f8a1b7d9SAlexander Kabaev 			  __s.size());
93*f8a1b7d9SAlexander Kabaev       }
94*f8a1b7d9SAlexander Kabaev 
95*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
96*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
97*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>&
98*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
_M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)99*f8a1b7d9SAlexander Kabaev     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
100*f8a1b7d9SAlexander Kabaev 		   _CharT __c)
101*f8a1b7d9SAlexander Kabaev     {
102*f8a1b7d9SAlexander Kabaev       _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
103*f8a1b7d9SAlexander Kabaev 
104*f8a1b7d9SAlexander Kabaev       const size_type __old_size = this->size();
105*f8a1b7d9SAlexander Kabaev       const size_type __new_size = __old_size + __n2 - __n1;
106*f8a1b7d9SAlexander Kabaev 
107*f8a1b7d9SAlexander Kabaev       if (__new_size <= this->capacity() && !this->_M_is_shared())
108*f8a1b7d9SAlexander Kabaev 	{
109*f8a1b7d9SAlexander Kabaev 	  _CharT* __p = this->_M_data() + __pos1;
110*f8a1b7d9SAlexander Kabaev 
111*f8a1b7d9SAlexander Kabaev 	  const size_type __how_much = __old_size - __pos1 - __n1;
112*f8a1b7d9SAlexander Kabaev 	  if (__how_much && __n1 != __n2)
113*f8a1b7d9SAlexander Kabaev 	    this->_S_move(__p + __n2, __p + __n1, __how_much);
114*f8a1b7d9SAlexander Kabaev 	}
115*f8a1b7d9SAlexander Kabaev       else
116*f8a1b7d9SAlexander Kabaev 	this->_M_mutate(__pos1, __n1, 0, __n2);
117*f8a1b7d9SAlexander Kabaev 
118*f8a1b7d9SAlexander Kabaev       if (__n2)
119*f8a1b7d9SAlexander Kabaev 	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
120*f8a1b7d9SAlexander Kabaev 
121*f8a1b7d9SAlexander Kabaev       this->_M_set_length(__new_size);
122*f8a1b7d9SAlexander Kabaev       return *this;
123*f8a1b7d9SAlexander Kabaev     }
124*f8a1b7d9SAlexander Kabaev 
125*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
126*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
127*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>&
128*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
_M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)129*f8a1b7d9SAlexander Kabaev     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
130*f8a1b7d9SAlexander Kabaev 	       const size_type __len2)
131*f8a1b7d9SAlexander Kabaev     {
132*f8a1b7d9SAlexander Kabaev       _M_check_length(__len1, __len2, "__versa_string::_M_replace");
133*f8a1b7d9SAlexander Kabaev 
134*f8a1b7d9SAlexander Kabaev       const size_type __old_size = this->size();
135*f8a1b7d9SAlexander Kabaev       const size_type __new_size = __old_size + __len2 - __len1;
136*f8a1b7d9SAlexander Kabaev 
137*f8a1b7d9SAlexander Kabaev       if (__new_size <= this->capacity() && !this->_M_is_shared())
138*f8a1b7d9SAlexander Kabaev 	{
139*f8a1b7d9SAlexander Kabaev 	  _CharT* __p = this->_M_data() + __pos;
140*f8a1b7d9SAlexander Kabaev 
141*f8a1b7d9SAlexander Kabaev 	  const size_type __how_much = __old_size - __pos - __len1;
142*f8a1b7d9SAlexander Kabaev 	  if (_M_disjunct(__s))
143*f8a1b7d9SAlexander Kabaev 	    {
144*f8a1b7d9SAlexander Kabaev 	      if (__how_much && __len1 != __len2)
145*f8a1b7d9SAlexander Kabaev 		this->_S_move(__p + __len2, __p + __len1, __how_much);
146*f8a1b7d9SAlexander Kabaev 	      if (__len2)
147*f8a1b7d9SAlexander Kabaev 		this->_S_copy(__p, __s, __len2);
148*f8a1b7d9SAlexander Kabaev 	    }
149*f8a1b7d9SAlexander Kabaev 	  else
150*f8a1b7d9SAlexander Kabaev 	    {
151*f8a1b7d9SAlexander Kabaev 	      // Work in-place.
152*f8a1b7d9SAlexander Kabaev 	      if (__len2 && __len2 <= __len1)
153*f8a1b7d9SAlexander Kabaev 		this->_S_move(__p, __s, __len2);
154*f8a1b7d9SAlexander Kabaev 	      if (__how_much && __len1 != __len2)
155*f8a1b7d9SAlexander Kabaev 		this->_S_move(__p + __len2, __p + __len1, __how_much);
156*f8a1b7d9SAlexander Kabaev 	      if (__len2 > __len1)
157*f8a1b7d9SAlexander Kabaev 		{
158*f8a1b7d9SAlexander Kabaev 		  if (__s + __len2 <= __p + __len1)
159*f8a1b7d9SAlexander Kabaev 		    this->_S_move(__p, __s, __len2);
160*f8a1b7d9SAlexander Kabaev 		  else if (__s >= __p + __len1)
161*f8a1b7d9SAlexander Kabaev 		    this->_S_copy(__p, __s + __len2 - __len1, __len2);
162*f8a1b7d9SAlexander Kabaev 		  else
163*f8a1b7d9SAlexander Kabaev 		    {
164*f8a1b7d9SAlexander Kabaev 		      const size_type __nleft = (__p + __len1) - __s;
165*f8a1b7d9SAlexander Kabaev 		      this->_S_move(__p, __s, __nleft);
166*f8a1b7d9SAlexander Kabaev 		      this->_S_copy(__p + __nleft, __p + __len2,
167*f8a1b7d9SAlexander Kabaev 				    __len2 - __nleft);
168*f8a1b7d9SAlexander Kabaev 		    }
169*f8a1b7d9SAlexander Kabaev 		}
170*f8a1b7d9SAlexander Kabaev 	    }
171*f8a1b7d9SAlexander Kabaev 	}
172*f8a1b7d9SAlexander Kabaev       else
173*f8a1b7d9SAlexander Kabaev 	this->_M_mutate(__pos, __len1, __s, __len2);
174*f8a1b7d9SAlexander Kabaev 
175*f8a1b7d9SAlexander Kabaev       this->_M_set_length(__new_size);
176*f8a1b7d9SAlexander Kabaev       return *this;
177*f8a1b7d9SAlexander Kabaev     }
178*f8a1b7d9SAlexander Kabaev 
179*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
180*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
181*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>
operator +(const __versa_string<_CharT,_Traits,_Alloc,_Base> & __lhs,const __versa_string<_CharT,_Traits,_Alloc,_Base> & __rhs)182*f8a1b7d9SAlexander Kabaev     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
183*f8a1b7d9SAlexander Kabaev 	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
184*f8a1b7d9SAlexander Kabaev     {
185*f8a1b7d9SAlexander Kabaev       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
186*f8a1b7d9SAlexander Kabaev       __str.reserve(__lhs.size() + __rhs.size());
187*f8a1b7d9SAlexander Kabaev       __str.append(__lhs);
188*f8a1b7d9SAlexander Kabaev       __str.append(__rhs);
189*f8a1b7d9SAlexander Kabaev       return __str;
190*f8a1b7d9SAlexander Kabaev     }
191*f8a1b7d9SAlexander Kabaev 
192*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
193*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
194*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>
operator +(const _CharT * __lhs,const __versa_string<_CharT,_Traits,_Alloc,_Base> & __rhs)195*f8a1b7d9SAlexander Kabaev     operator+(const _CharT* __lhs,
196*f8a1b7d9SAlexander Kabaev 	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
197*f8a1b7d9SAlexander Kabaev     {
198*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string(__lhs);
199*f8a1b7d9SAlexander Kabaev       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
200*f8a1b7d9SAlexander Kabaev       typedef typename __string_type::size_type	  __size_type;
201*f8a1b7d9SAlexander Kabaev       const __size_type __len = _Traits::length(__lhs);
202*f8a1b7d9SAlexander Kabaev       __string_type __str;
203*f8a1b7d9SAlexander Kabaev       __str.reserve(__len + __rhs.size());
204*f8a1b7d9SAlexander Kabaev       __str.append(__lhs, __len);
205*f8a1b7d9SAlexander Kabaev       __str.append(__rhs);
206*f8a1b7d9SAlexander Kabaev       return __str;
207*f8a1b7d9SAlexander Kabaev     }
208*f8a1b7d9SAlexander Kabaev 
209*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
210*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
211*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>
operator +(_CharT __lhs,const __versa_string<_CharT,_Traits,_Alloc,_Base> & __rhs)212*f8a1b7d9SAlexander Kabaev     operator+(_CharT __lhs,
213*f8a1b7d9SAlexander Kabaev 	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
214*f8a1b7d9SAlexander Kabaev     {
215*f8a1b7d9SAlexander Kabaev       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
216*f8a1b7d9SAlexander Kabaev       __str.reserve(__rhs.size() + 1);
217*f8a1b7d9SAlexander Kabaev       __str.push_back(__lhs);
218*f8a1b7d9SAlexander Kabaev       __str.append(__rhs);
219*f8a1b7d9SAlexander Kabaev       return __str;
220*f8a1b7d9SAlexander Kabaev     }
221*f8a1b7d9SAlexander Kabaev 
222*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
223*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
224*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>
operator +(const __versa_string<_CharT,_Traits,_Alloc,_Base> & __lhs,const _CharT * __rhs)225*f8a1b7d9SAlexander Kabaev     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
226*f8a1b7d9SAlexander Kabaev 	      const _CharT* __rhs)
227*f8a1b7d9SAlexander Kabaev     {
228*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string(__rhs);
229*f8a1b7d9SAlexander Kabaev       typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
230*f8a1b7d9SAlexander Kabaev       typedef typename __string_type::size_type	  __size_type;
231*f8a1b7d9SAlexander Kabaev       const __size_type __len = _Traits::length(__rhs);
232*f8a1b7d9SAlexander Kabaev       __string_type __str;
233*f8a1b7d9SAlexander Kabaev       __str.reserve(__lhs.size() + __len);
234*f8a1b7d9SAlexander Kabaev       __str.append(__lhs);
235*f8a1b7d9SAlexander Kabaev       __str.append(__rhs, __len);
236*f8a1b7d9SAlexander Kabaev       return __str;
237*f8a1b7d9SAlexander Kabaev     }
238*f8a1b7d9SAlexander Kabaev 
239*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
240*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
241*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>
operator +(const __versa_string<_CharT,_Traits,_Alloc,_Base> & __lhs,_CharT __rhs)242*f8a1b7d9SAlexander Kabaev     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
243*f8a1b7d9SAlexander Kabaev 	      _CharT __rhs)
244*f8a1b7d9SAlexander Kabaev     {
245*f8a1b7d9SAlexander Kabaev       __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
246*f8a1b7d9SAlexander Kabaev       __str.reserve(__lhs.size() + 1);
247*f8a1b7d9SAlexander Kabaev       __str.append(__lhs);
248*f8a1b7d9SAlexander Kabaev       __str.push_back(__rhs);
249*f8a1b7d9SAlexander Kabaev       return __str;
250*f8a1b7d9SAlexander Kabaev     }
251*f8a1b7d9SAlexander Kabaev 
252*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
253*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
254*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
255*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
copy(_CharT * __s,size_type __n,size_type __pos) const256*f8a1b7d9SAlexander Kabaev     copy(_CharT* __s, size_type __n, size_type __pos) const
257*f8a1b7d9SAlexander Kabaev     {
258*f8a1b7d9SAlexander Kabaev       _M_check(__pos, "__versa_string::copy");
259*f8a1b7d9SAlexander Kabaev       __n = _M_limit(__pos, __n);
260*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
261*f8a1b7d9SAlexander Kabaev       if (__n)
262*f8a1b7d9SAlexander Kabaev 	this->_S_copy(__s, this->_M_data() + __pos, __n);
263*f8a1b7d9SAlexander Kabaev       // 21.3.5.7 par 3: do not append null.  (good.)
264*f8a1b7d9SAlexander Kabaev       return __n;
265*f8a1b7d9SAlexander Kabaev     }
266*f8a1b7d9SAlexander Kabaev 
267*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
268*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
269*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
270*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find(const _CharT * __s,size_type __pos,size_type __n) const271*f8a1b7d9SAlexander Kabaev     find(const _CharT* __s, size_type __pos, size_type __n) const
272*f8a1b7d9SAlexander Kabaev     {
273*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
274*f8a1b7d9SAlexander Kabaev       const size_type __size = this->size();
275*f8a1b7d9SAlexander Kabaev       const _CharT* __data = this->_M_data();
276*f8a1b7d9SAlexander Kabaev 
277*f8a1b7d9SAlexander Kabaev       if (__n == 0)
278*f8a1b7d9SAlexander Kabaev 	return __pos <= __size ? __pos : npos;
279*f8a1b7d9SAlexander Kabaev 
280*f8a1b7d9SAlexander Kabaev       if (__n <= __size)
281*f8a1b7d9SAlexander Kabaev 	{
282*f8a1b7d9SAlexander Kabaev 	  for (; __pos <= __size - __n; ++__pos)
283*f8a1b7d9SAlexander Kabaev 	    if (traits_type::eq(__data[__pos], __s[0])
284*f8a1b7d9SAlexander Kabaev 		&& traits_type::compare(__data + __pos + 1,
285*f8a1b7d9SAlexander Kabaev 					__s + 1, __n - 1) == 0)
286*f8a1b7d9SAlexander Kabaev 	      return __pos;
287*f8a1b7d9SAlexander Kabaev 	}
288*f8a1b7d9SAlexander Kabaev       return npos;
289*f8a1b7d9SAlexander Kabaev     }
290*f8a1b7d9SAlexander Kabaev 
291*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
292*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
293*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
294*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find(_CharT __c,size_type __pos) const295*f8a1b7d9SAlexander Kabaev     find(_CharT __c, size_type __pos) const
296*f8a1b7d9SAlexander Kabaev     {
297*f8a1b7d9SAlexander Kabaev       size_type __ret = npos;
298*f8a1b7d9SAlexander Kabaev       const size_type __size = this->size();
299*f8a1b7d9SAlexander Kabaev       if (__pos < __size)
300*f8a1b7d9SAlexander Kabaev 	{
301*f8a1b7d9SAlexander Kabaev 	  const _CharT* __data = this->_M_data();
302*f8a1b7d9SAlexander Kabaev 	  const size_type __n = __size - __pos;
303*f8a1b7d9SAlexander Kabaev 	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
304*f8a1b7d9SAlexander Kabaev 	  if (__p)
305*f8a1b7d9SAlexander Kabaev 	    __ret = __p - __data;
306*f8a1b7d9SAlexander Kabaev 	}
307*f8a1b7d9SAlexander Kabaev       return __ret;
308*f8a1b7d9SAlexander Kabaev     }
309*f8a1b7d9SAlexander Kabaev 
310*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
311*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
312*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
313*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
rfind(const _CharT * __s,size_type __pos,size_type __n) const314*f8a1b7d9SAlexander Kabaev     rfind(const _CharT* __s, size_type __pos, size_type __n) const
315*f8a1b7d9SAlexander Kabaev     {
316*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
317*f8a1b7d9SAlexander Kabaev       const size_type __size = this->size();
318*f8a1b7d9SAlexander Kabaev       if (__n <= __size)
319*f8a1b7d9SAlexander Kabaev 	{
320*f8a1b7d9SAlexander Kabaev 	  __pos = std::min(size_type(__size - __n), __pos);
321*f8a1b7d9SAlexander Kabaev 	  const _CharT* __data = this->_M_data();
322*f8a1b7d9SAlexander Kabaev 	  do
323*f8a1b7d9SAlexander Kabaev 	    {
324*f8a1b7d9SAlexander Kabaev 	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
325*f8a1b7d9SAlexander Kabaev 		return __pos;
326*f8a1b7d9SAlexander Kabaev 	    }
327*f8a1b7d9SAlexander Kabaev 	  while (__pos-- > 0);
328*f8a1b7d9SAlexander Kabaev 	}
329*f8a1b7d9SAlexander Kabaev       return npos;
330*f8a1b7d9SAlexander Kabaev     }
331*f8a1b7d9SAlexander Kabaev 
332*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
333*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
334*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
335*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
rfind(_CharT __c,size_type __pos) const336*f8a1b7d9SAlexander Kabaev     rfind(_CharT __c, size_type __pos) const
337*f8a1b7d9SAlexander Kabaev     {
338*f8a1b7d9SAlexander Kabaev       size_type __size = this->size();
339*f8a1b7d9SAlexander Kabaev       if (__size)
340*f8a1b7d9SAlexander Kabaev 	{
341*f8a1b7d9SAlexander Kabaev 	  if (--__size > __pos)
342*f8a1b7d9SAlexander Kabaev 	    __size = __pos;
343*f8a1b7d9SAlexander Kabaev 	  for (++__size; __size-- > 0; )
344*f8a1b7d9SAlexander Kabaev 	    if (traits_type::eq(this->_M_data()[__size], __c))
345*f8a1b7d9SAlexander Kabaev 	      return __size;
346*f8a1b7d9SAlexander Kabaev 	}
347*f8a1b7d9SAlexander Kabaev       return npos;
348*f8a1b7d9SAlexander Kabaev     }
349*f8a1b7d9SAlexander Kabaev 
350*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
351*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
352*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
353*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_first_of(const _CharT * __s,size_type __pos,size_type __n) const354*f8a1b7d9SAlexander Kabaev     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
355*f8a1b7d9SAlexander Kabaev     {
356*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
357*f8a1b7d9SAlexander Kabaev       for (; __n && __pos < this->size(); ++__pos)
358*f8a1b7d9SAlexander Kabaev 	{
359*f8a1b7d9SAlexander Kabaev 	  const _CharT* __p = traits_type::find(__s, __n,
360*f8a1b7d9SAlexander Kabaev 						this->_M_data()[__pos]);
361*f8a1b7d9SAlexander Kabaev 	  if (__p)
362*f8a1b7d9SAlexander Kabaev 	    return __pos;
363*f8a1b7d9SAlexander Kabaev 	}
364*f8a1b7d9SAlexander Kabaev       return npos;
365*f8a1b7d9SAlexander Kabaev     }
366*f8a1b7d9SAlexander Kabaev 
367*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
368*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
369*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
370*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_last_of(const _CharT * __s,size_type __pos,size_type __n) const371*f8a1b7d9SAlexander Kabaev     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
372*f8a1b7d9SAlexander Kabaev     {
373*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
374*f8a1b7d9SAlexander Kabaev       size_type __size = this->size();
375*f8a1b7d9SAlexander Kabaev       if (__size && __n)
376*f8a1b7d9SAlexander Kabaev 	{
377*f8a1b7d9SAlexander Kabaev 	  if (--__size > __pos)
378*f8a1b7d9SAlexander Kabaev 	    __size = __pos;
379*f8a1b7d9SAlexander Kabaev 	  do
380*f8a1b7d9SAlexander Kabaev 	    {
381*f8a1b7d9SAlexander Kabaev 	      if (traits_type::find(__s, __n, this->_M_data()[__size]))
382*f8a1b7d9SAlexander Kabaev 		return __size;
383*f8a1b7d9SAlexander Kabaev 	    }
384*f8a1b7d9SAlexander Kabaev 	  while (__size-- != 0);
385*f8a1b7d9SAlexander Kabaev 	}
386*f8a1b7d9SAlexander Kabaev       return npos;
387*f8a1b7d9SAlexander Kabaev     }
388*f8a1b7d9SAlexander Kabaev 
389*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
390*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
391*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
392*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const393*f8a1b7d9SAlexander Kabaev     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
394*f8a1b7d9SAlexander Kabaev     {
395*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
396*f8a1b7d9SAlexander Kabaev       for (; __pos < this->size(); ++__pos)
397*f8a1b7d9SAlexander Kabaev 	if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
398*f8a1b7d9SAlexander Kabaev 	  return __pos;
399*f8a1b7d9SAlexander Kabaev       return npos;
400*f8a1b7d9SAlexander Kabaev     }
401*f8a1b7d9SAlexander Kabaev 
402*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
403*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
404*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
405*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_first_not_of(_CharT __c,size_type __pos) const406*f8a1b7d9SAlexander Kabaev     find_first_not_of(_CharT __c, size_type __pos) const
407*f8a1b7d9SAlexander Kabaev     {
408*f8a1b7d9SAlexander Kabaev       for (; __pos < this->size(); ++__pos)
409*f8a1b7d9SAlexander Kabaev 	if (!traits_type::eq(this->_M_data()[__pos], __c))
410*f8a1b7d9SAlexander Kabaev 	  return __pos;
411*f8a1b7d9SAlexander Kabaev       return npos;
412*f8a1b7d9SAlexander Kabaev     }
413*f8a1b7d9SAlexander Kabaev 
414*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
415*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
416*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
417*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const418*f8a1b7d9SAlexander Kabaev     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
419*f8a1b7d9SAlexander Kabaev     {
420*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n);
421*f8a1b7d9SAlexander Kabaev       size_type __size = this->size();
422*f8a1b7d9SAlexander Kabaev       if (__size)
423*f8a1b7d9SAlexander Kabaev 	{
424*f8a1b7d9SAlexander Kabaev 	  if (--__size > __pos)
425*f8a1b7d9SAlexander Kabaev 	    __size = __pos;
426*f8a1b7d9SAlexander Kabaev 	  do
427*f8a1b7d9SAlexander Kabaev 	    {
428*f8a1b7d9SAlexander Kabaev 	      if (!traits_type::find(__s, __n, this->_M_data()[__size]))
429*f8a1b7d9SAlexander Kabaev 		return __size;
430*f8a1b7d9SAlexander Kabaev 	    }
431*f8a1b7d9SAlexander Kabaev 	  while (__size--);
432*f8a1b7d9SAlexander Kabaev 	}
433*f8a1b7d9SAlexander Kabaev       return npos;
434*f8a1b7d9SAlexander Kabaev     }
435*f8a1b7d9SAlexander Kabaev 
436*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
437*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
438*f8a1b7d9SAlexander Kabaev     typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
439*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
find_last_not_of(_CharT __c,size_type __pos) const440*f8a1b7d9SAlexander Kabaev     find_last_not_of(_CharT __c, size_type __pos) const
441*f8a1b7d9SAlexander Kabaev     {
442*f8a1b7d9SAlexander Kabaev       size_type __size = this->size();
443*f8a1b7d9SAlexander Kabaev       if (__size)
444*f8a1b7d9SAlexander Kabaev 	{
445*f8a1b7d9SAlexander Kabaev 	  if (--__size > __pos)
446*f8a1b7d9SAlexander Kabaev 	    __size = __pos;
447*f8a1b7d9SAlexander Kabaev 	  do
448*f8a1b7d9SAlexander Kabaev 	    {
449*f8a1b7d9SAlexander Kabaev 	      if (!traits_type::eq(this->_M_data()[__size], __c))
450*f8a1b7d9SAlexander Kabaev 		return __size;
451*f8a1b7d9SAlexander Kabaev 	    }
452*f8a1b7d9SAlexander Kabaev 	  while (__size--);
453*f8a1b7d9SAlexander Kabaev 	}
454*f8a1b7d9SAlexander Kabaev       return npos;
455*f8a1b7d9SAlexander Kabaev     }
456*f8a1b7d9SAlexander Kabaev 
457*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
458*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
459*f8a1b7d9SAlexander Kabaev     int
460*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
compare(size_type __pos,size_type __n,const __versa_string & __str) const461*f8a1b7d9SAlexander Kabaev     compare(size_type __pos, size_type __n, const __versa_string& __str) const
462*f8a1b7d9SAlexander Kabaev     {
463*f8a1b7d9SAlexander Kabaev       _M_check(__pos, "__versa_string::compare");
464*f8a1b7d9SAlexander Kabaev       __n = _M_limit(__pos, __n);
465*f8a1b7d9SAlexander Kabaev       const size_type __osize = __str.size();
466*f8a1b7d9SAlexander Kabaev       const size_type __len = std::min(__n, __osize);
467*f8a1b7d9SAlexander Kabaev       int __r = traits_type::compare(this->_M_data() + __pos,
468*f8a1b7d9SAlexander Kabaev 				     __str.data(), __len);
469*f8a1b7d9SAlexander Kabaev       if (!__r)
470*f8a1b7d9SAlexander Kabaev 	__r = __n - __osize;
471*f8a1b7d9SAlexander Kabaev       return __r;
472*f8a1b7d9SAlexander Kabaev     }
473*f8a1b7d9SAlexander Kabaev 
474*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
475*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
476*f8a1b7d9SAlexander Kabaev     int
477*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
compare(size_type __pos1,size_type __n1,const __versa_string & __str,size_type __pos2,size_type __n2) const478*f8a1b7d9SAlexander Kabaev     compare(size_type __pos1, size_type __n1, const __versa_string& __str,
479*f8a1b7d9SAlexander Kabaev 	    size_type __pos2, size_type __n2) const
480*f8a1b7d9SAlexander Kabaev     {
481*f8a1b7d9SAlexander Kabaev       _M_check(__pos1, "__versa_string::compare");
482*f8a1b7d9SAlexander Kabaev       __str._M_check(__pos2, "__versa_string::compare");
483*f8a1b7d9SAlexander Kabaev       __n1 = _M_limit(__pos1, __n1);
484*f8a1b7d9SAlexander Kabaev       __n2 = __str._M_limit(__pos2, __n2);
485*f8a1b7d9SAlexander Kabaev       const size_type __len = std::min(__n1, __n2);
486*f8a1b7d9SAlexander Kabaev       int __r = traits_type::compare(this->_M_data() + __pos1,
487*f8a1b7d9SAlexander Kabaev 				     __str.data() + __pos2, __len);
488*f8a1b7d9SAlexander Kabaev       if (!__r)
489*f8a1b7d9SAlexander Kabaev 	__r = __n1 - __n2;
490*f8a1b7d9SAlexander Kabaev       return __r;
491*f8a1b7d9SAlexander Kabaev     }
492*f8a1b7d9SAlexander Kabaev 
493*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
494*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
495*f8a1b7d9SAlexander Kabaev     int
496*f8a1b7d9SAlexander Kabaev     __versa_string<_CharT, _Traits, _Alloc, _Base>::
compare(const _CharT * __s) const497*f8a1b7d9SAlexander Kabaev     compare(const _CharT* __s) const
498*f8a1b7d9SAlexander Kabaev     {
499*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string(__s);
500*f8a1b7d9SAlexander Kabaev       const size_type __size = this->size();
501*f8a1b7d9SAlexander Kabaev       const size_type __osize = traits_type::length(__s);
502*f8a1b7d9SAlexander Kabaev       const size_type __len = std::min(__size, __osize);
503*f8a1b7d9SAlexander Kabaev       int __r = traits_type::compare(this->_M_data(), __s, __len);
504*f8a1b7d9SAlexander Kabaev       if (!__r)
505*f8a1b7d9SAlexander Kabaev 	__r = __size - __osize;
506*f8a1b7d9SAlexander Kabaev       return __r;
507*f8a1b7d9SAlexander Kabaev     }
508*f8a1b7d9SAlexander Kabaev 
509*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
510*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
511*f8a1b7d9SAlexander Kabaev     int
512*f8a1b7d9SAlexander Kabaev     __versa_string <_CharT, _Traits, _Alloc, _Base>::
compare(size_type __pos,size_type __n1,const _CharT * __s) const513*f8a1b7d9SAlexander Kabaev     compare(size_type __pos, size_type __n1, const _CharT* __s) const
514*f8a1b7d9SAlexander Kabaev     {
515*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string(__s);
516*f8a1b7d9SAlexander Kabaev       _M_check(__pos, "__versa_string::compare");
517*f8a1b7d9SAlexander Kabaev       __n1 = _M_limit(__pos, __n1);
518*f8a1b7d9SAlexander Kabaev       const size_type __osize = traits_type::length(__s);
519*f8a1b7d9SAlexander Kabaev       const size_type __len = std::min(__n1, __osize);
520*f8a1b7d9SAlexander Kabaev       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
521*f8a1b7d9SAlexander Kabaev       if (!__r)
522*f8a1b7d9SAlexander Kabaev 	__r = __n1 - __osize;
523*f8a1b7d9SAlexander Kabaev       return __r;
524*f8a1b7d9SAlexander Kabaev     }
525*f8a1b7d9SAlexander Kabaev 
526*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
527*f8a1b7d9SAlexander Kabaev 	   template <typename, typename, typename> class _Base>
528*f8a1b7d9SAlexander Kabaev     int
529*f8a1b7d9SAlexander Kabaev     __versa_string <_CharT, _Traits, _Alloc, _Base>::
compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const530*f8a1b7d9SAlexander Kabaev     compare(size_type __pos, size_type __n1, const _CharT* __s,
531*f8a1b7d9SAlexander Kabaev 	    size_type __n2) const
532*f8a1b7d9SAlexander Kabaev     {
533*f8a1b7d9SAlexander Kabaev       __glibcxx_requires_string_len(__s, __n2);
534*f8a1b7d9SAlexander Kabaev       _M_check(__pos, "__versa_string::compare");
535*f8a1b7d9SAlexander Kabaev       __n1 = _M_limit(__pos, __n1);
536*f8a1b7d9SAlexander Kabaev       const size_type __len = std::min(__n1, __n2);
537*f8a1b7d9SAlexander Kabaev       int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
538*f8a1b7d9SAlexander Kabaev       if (!__r)
539*f8a1b7d9SAlexander Kabaev 	__r = __n1 - __n2;
540*f8a1b7d9SAlexander Kabaev       return __r;
541*f8a1b7d9SAlexander Kabaev     }
542*f8a1b7d9SAlexander Kabaev 
543*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
544*f8a1b7d9SAlexander Kabaev 
_GLIBCXX_BEGIN_NAMESPACE(std)545*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
546*f8a1b7d9SAlexander Kabaev 
547*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
548*f8a1b7d9SAlexander Kabaev            template <typename, typename, typename> class _Base>
549*f8a1b7d9SAlexander Kabaev     basic_istream<_CharT, _Traits>&
550*f8a1b7d9SAlexander Kabaev     operator>>(basic_istream<_CharT, _Traits>& __in,
551*f8a1b7d9SAlexander Kabaev 	       __gnu_cxx::__versa_string<_CharT, _Traits,
552*f8a1b7d9SAlexander Kabaev 	                                 _Alloc, _Base>& __str)
553*f8a1b7d9SAlexander Kabaev     {
554*f8a1b7d9SAlexander Kabaev       typedef basic_istream<_CharT, _Traits>	        __istream_type;
555*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::int_type		__int_type;
556*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::__streambuf_type __streambuf_type;
557*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::__ctype_type	__ctype_type;
558*f8a1b7d9SAlexander Kabaev       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
559*f8a1b7d9SAlexander Kabaev 	                                                __string_type;
560*f8a1b7d9SAlexander Kabaev       typedef typename __string_type::size_type		__size_type;
561*f8a1b7d9SAlexander Kabaev 
562*f8a1b7d9SAlexander Kabaev       __size_type __extracted = 0;
563*f8a1b7d9SAlexander Kabaev       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
564*f8a1b7d9SAlexander Kabaev       typename __istream_type::sentry __cerb(__in, false);
565*f8a1b7d9SAlexander Kabaev       if (__cerb)
566*f8a1b7d9SAlexander Kabaev 	{
567*f8a1b7d9SAlexander Kabaev 	  try
568*f8a1b7d9SAlexander Kabaev 	    {
569*f8a1b7d9SAlexander Kabaev 	      // Avoid reallocation for common case.
570*f8a1b7d9SAlexander Kabaev 	      __str.erase();
571*f8a1b7d9SAlexander Kabaev 	      _CharT __buf[128];
572*f8a1b7d9SAlexander Kabaev 	      __size_type __len = 0;
573*f8a1b7d9SAlexander Kabaev 	      const streamsize __w = __in.width();
574*f8a1b7d9SAlexander Kabaev 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
575*f8a1b7d9SAlexander Kabaev 		                              : __str.max_size();
576*f8a1b7d9SAlexander Kabaev 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
577*f8a1b7d9SAlexander Kabaev 	      const __int_type __eof = _Traits::eof();
578*f8a1b7d9SAlexander Kabaev 	      __streambuf_type* __sb = __in.rdbuf();
579*f8a1b7d9SAlexander Kabaev 	      __int_type __c = __sb->sgetc();
580*f8a1b7d9SAlexander Kabaev 
581*f8a1b7d9SAlexander Kabaev 	      while (__extracted < __n
582*f8a1b7d9SAlexander Kabaev 		     && !_Traits::eq_int_type(__c, __eof)
583*f8a1b7d9SAlexander Kabaev 		     && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
584*f8a1b7d9SAlexander Kabaev 		{
585*f8a1b7d9SAlexander Kabaev 		  if (__len == sizeof(__buf) / sizeof(_CharT))
586*f8a1b7d9SAlexander Kabaev 		    {
587*f8a1b7d9SAlexander Kabaev 		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
588*f8a1b7d9SAlexander Kabaev 		      __len = 0;
589*f8a1b7d9SAlexander Kabaev 		    }
590*f8a1b7d9SAlexander Kabaev 		  __buf[__len++] = _Traits::to_char_type(__c);
591*f8a1b7d9SAlexander Kabaev 		  ++__extracted;
592*f8a1b7d9SAlexander Kabaev 		  __c = __sb->snextc();
593*f8a1b7d9SAlexander Kabaev 		}
594*f8a1b7d9SAlexander Kabaev 	      __str.append(__buf, __len);
595*f8a1b7d9SAlexander Kabaev 
596*f8a1b7d9SAlexander Kabaev 	      if (_Traits::eq_int_type(__c, __eof))
597*f8a1b7d9SAlexander Kabaev 		__err |= ios_base::eofbit;
598*f8a1b7d9SAlexander Kabaev 	      __in.width(0);
599*f8a1b7d9SAlexander Kabaev 	    }
600*f8a1b7d9SAlexander Kabaev 	  catch(...)
601*f8a1b7d9SAlexander Kabaev 	    {
602*f8a1b7d9SAlexander Kabaev 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
603*f8a1b7d9SAlexander Kabaev 	      // 91. Description of operator>> and getline() for string<>
604*f8a1b7d9SAlexander Kabaev 	      // might cause endless loop
605*f8a1b7d9SAlexander Kabaev 	      __in._M_setstate(ios_base::badbit);
606*f8a1b7d9SAlexander Kabaev 	    }
607*f8a1b7d9SAlexander Kabaev 	}
608*f8a1b7d9SAlexander Kabaev       // 211.  operator>>(istream&, string&) doesn't set failbit
609*f8a1b7d9SAlexander Kabaev       if (!__extracted)
610*f8a1b7d9SAlexander Kabaev 	__err |= ios_base::failbit;
611*f8a1b7d9SAlexander Kabaev       if (__err)
612*f8a1b7d9SAlexander Kabaev 	__in.setstate(__err);
613*f8a1b7d9SAlexander Kabaev       return __in;
614*f8a1b7d9SAlexander Kabaev     }
615*f8a1b7d9SAlexander Kabaev 
616*f8a1b7d9SAlexander Kabaev   template<typename _CharT, typename _Traits, typename _Alloc,
617*f8a1b7d9SAlexander Kabaev            template <typename, typename, typename> class _Base>
618*f8a1b7d9SAlexander Kabaev     basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT,_Traits> & __in,__gnu_cxx::__versa_string<_CharT,_Traits,_Alloc,_Base> & __str,_CharT __delim)619*f8a1b7d9SAlexander Kabaev     getline(basic_istream<_CharT, _Traits>& __in,
620*f8a1b7d9SAlexander Kabaev 	    __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
621*f8a1b7d9SAlexander Kabaev 	    _CharT __delim)
622*f8a1b7d9SAlexander Kabaev     {
623*f8a1b7d9SAlexander Kabaev       typedef basic_istream<_CharT, _Traits>	        __istream_type;
624*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::int_type		__int_type;
625*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::__streambuf_type __streambuf_type;
626*f8a1b7d9SAlexander Kabaev       typedef typename __istream_type::__ctype_type	__ctype_type;
627*f8a1b7d9SAlexander Kabaev       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
628*f8a1b7d9SAlexander Kabaev 	                                                __string_type;
629*f8a1b7d9SAlexander Kabaev       typedef typename __string_type::size_type		__size_type;
630*f8a1b7d9SAlexander Kabaev 
631*f8a1b7d9SAlexander Kabaev       __size_type __extracted = 0;
632*f8a1b7d9SAlexander Kabaev       const __size_type __n = __str.max_size();
633*f8a1b7d9SAlexander Kabaev       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
634*f8a1b7d9SAlexander Kabaev       typename __istream_type::sentry __cerb(__in, true);
635*f8a1b7d9SAlexander Kabaev       if (__cerb)
636*f8a1b7d9SAlexander Kabaev 	{
637*f8a1b7d9SAlexander Kabaev 	  try
638*f8a1b7d9SAlexander Kabaev 	    {
639*f8a1b7d9SAlexander Kabaev 	      // Avoid reallocation for common case.
640*f8a1b7d9SAlexander Kabaev 	      __str.erase();
641*f8a1b7d9SAlexander Kabaev 	      _CharT __buf[128];
642*f8a1b7d9SAlexander Kabaev 	      __size_type __len = 0;
643*f8a1b7d9SAlexander Kabaev 	      const __int_type __idelim = _Traits::to_int_type(__delim);
644*f8a1b7d9SAlexander Kabaev 	      const __int_type __eof = _Traits::eof();
645*f8a1b7d9SAlexander Kabaev 	      __streambuf_type* __sb = __in.rdbuf();
646*f8a1b7d9SAlexander Kabaev 	      __int_type __c = __sb->sgetc();
647*f8a1b7d9SAlexander Kabaev 
648*f8a1b7d9SAlexander Kabaev 	      while (__extracted < __n
649*f8a1b7d9SAlexander Kabaev 		     && !_Traits::eq_int_type(__c, __eof)
650*f8a1b7d9SAlexander Kabaev 		     && !_Traits::eq_int_type(__c, __idelim))
651*f8a1b7d9SAlexander Kabaev 		{
652*f8a1b7d9SAlexander Kabaev 		  if (__len == sizeof(__buf) / sizeof(_CharT))
653*f8a1b7d9SAlexander Kabaev 		    {
654*f8a1b7d9SAlexander Kabaev 		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
655*f8a1b7d9SAlexander Kabaev 		      __len = 0;
656*f8a1b7d9SAlexander Kabaev 		    }
657*f8a1b7d9SAlexander Kabaev 		  __buf[__len++] = _Traits::to_char_type(__c);
658*f8a1b7d9SAlexander Kabaev 		  ++__extracted;
659*f8a1b7d9SAlexander Kabaev 		  __c = __sb->snextc();
660*f8a1b7d9SAlexander Kabaev 		}
661*f8a1b7d9SAlexander Kabaev 	      __str.append(__buf, __len);
662*f8a1b7d9SAlexander Kabaev 
663*f8a1b7d9SAlexander Kabaev 	      if (_Traits::eq_int_type(__c, __eof))
664*f8a1b7d9SAlexander Kabaev 		__err |= ios_base::eofbit;
665*f8a1b7d9SAlexander Kabaev 	      else if (_Traits::eq_int_type(__c, __idelim))
666*f8a1b7d9SAlexander Kabaev 		{
667*f8a1b7d9SAlexander Kabaev 		  ++__extracted;
668*f8a1b7d9SAlexander Kabaev 		  __sb->sbumpc();
669*f8a1b7d9SAlexander Kabaev 		}
670*f8a1b7d9SAlexander Kabaev 	      else
671*f8a1b7d9SAlexander Kabaev 		__err |= ios_base::failbit;
672*f8a1b7d9SAlexander Kabaev 	    }
673*f8a1b7d9SAlexander Kabaev 	  catch(...)
674*f8a1b7d9SAlexander Kabaev 	    {
675*f8a1b7d9SAlexander Kabaev 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
676*f8a1b7d9SAlexander Kabaev 	      // 91. Description of operator>> and getline() for string<>
677*f8a1b7d9SAlexander Kabaev 	      // might cause endless loop
678*f8a1b7d9SAlexander Kabaev 	      __in._M_setstate(ios_base::badbit);
679*f8a1b7d9SAlexander Kabaev 	    }
680*f8a1b7d9SAlexander Kabaev 	}
681*f8a1b7d9SAlexander Kabaev       if (!__extracted)
682*f8a1b7d9SAlexander Kabaev 	__err |= ios_base::failbit;
683*f8a1b7d9SAlexander Kabaev       if (__err)
684*f8a1b7d9SAlexander Kabaev 	__in.setstate(__err);
685*f8a1b7d9SAlexander Kabaev       return __in;
686*f8a1b7d9SAlexander Kabaev     }
687*f8a1b7d9SAlexander Kabaev 
688*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
689*f8a1b7d9SAlexander Kabaev 
690*f8a1b7d9SAlexander Kabaev #endif // _VSTRING_TCC
691