00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #ifndef _CPP_BITS_STRING_TCC
00042 #define _CPP_BITS_STRING_TCC 1
00043 
00044 #pragma GCC system_header
00045 
00046 namespace std
00047 {
00048   template<typename _CharT, typename _Traits, typename _Alloc>
00049     const typename basic_string<_CharT, _Traits, _Alloc>::size_type 
00050     basic_string<_CharT, _Traits, _Alloc>::
00051     _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
00052 
00053   template<typename _CharT, typename _Traits, typename _Alloc>
00054     const _CharT 
00055     basic_string<_CharT, _Traits, _Alloc>::
00056     _Rep::_S_terminal = _CharT();
00057 
00058   template<typename _CharT, typename _Traits, typename _Alloc>
00059     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
00060     basic_string<_CharT, _Traits, _Alloc>::npos;
00061 
00062   
00063   
00064   template<typename _CharT, typename _Traits, typename _Alloc>
00065     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00066     basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
00067     (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
00068 
00069   
00070   
00071   
00072   
00073   template<typename _CharT, typename _Traits, typename _Alloc>
00074     template<typename _InIter>
00075       _CharT*
00076       basic_string<_CharT, _Traits, _Alloc>::
00077       _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
00078            input_iterator_tag)
00079       {
00080     if (__beg == __end && __a == _Alloc())
00081       return _S_empty_rep()._M_refcopy();
00082     
00083     _CharT __buf[100];
00084     size_type __i = 0;
00085     while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT))
00086       { 
00087         __buf[__i++] = *__beg; 
00088         ++__beg; 
00089       }
00090     _Rep* __r = _Rep::_S_create(__i, __a);
00091     traits_type::copy(__r->_M_refdata(), __buf, __i);
00092     __r->_M_length = __i;
00093     try 
00094       {
00095         
00096         
00097         
00098         for (;;)
00099           {
00100         _CharT* __p = __r->_M_refdata() + __r->_M_length;
00101         _CharT* __last = __r->_M_refdata() + __r->_M_capacity;
00102         for (;;)
00103           {
00104             if (__beg == __end)
00105               {
00106             __r->_M_length = __p - __r->_M_refdata();
00107             *__p = _Rep::_S_terminal;       
00108             return __r->_M_refdata();
00109               }
00110             if (__p == __last)
00111               break;
00112             *__p++ = *__beg; 
00113             ++__beg;
00114           }
00115         
00116         size_type __len = __p - __r->_M_refdata();
00117         _Rep* __another = _Rep::_S_create(__len + 1, __a);
00118         traits_type::copy(__another->_M_refdata(), 
00119                   __r->_M_refdata(), __len);
00120         __r->_M_destroy(__a);
00121         __r = __another;
00122         __r->_M_length = __len;
00123           }
00124       }
00125     catch(...) 
00126       {
00127         __r->_M_destroy(__a); 
00128         __throw_exception_again;
00129       }
00130     return 0;
00131       }
00132   
00133   template<typename _CharT, typename _Traits, typename _Alloc>
00134     template <class _InIter>
00135       _CharT*
00136       basic_string<_CharT, _Traits, _Alloc>::
00137       _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 
00138            forward_iterator_tag)
00139       {
00140     size_type __dnew = static_cast<size_type>(distance(__beg, __end));
00141 
00142     
00143     if (__builtin_expect(__beg == _InIter(0), 0))
00144       __throw_logic_error("attempt to create string with null pointer");
00145     
00146     if (__beg == __end && __a == _Alloc())
00147       return _S_empty_rep()._M_refcopy();
00148 
00149     
00150     _Rep* __r = _Rep::_S_create(__dnew, __a);
00151     try 
00152       { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
00153     catch(...) 
00154       { 
00155         __r->_M_destroy(__a); 
00156         __throw_exception_again;
00157       }
00158     __r->_M_length = __dnew;
00159 
00160     __r->_M_refdata()[__dnew] = _Rep::_S_terminal;  
00161     return __r->_M_refdata();
00162       }
00163 
00164   template<typename _CharT, typename _Traits, typename _Alloc>
00165     _CharT*
00166     basic_string<_CharT, _Traits, _Alloc>::
00167     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
00168     {
00169       if (__n == 0 && __a == _Alloc())
00170     return _S_empty_rep()._M_refcopy();
00171 
00172       
00173       _Rep* __r = _Rep::_S_create(__n, __a);
00174       try 
00175     { 
00176       if (__n) 
00177         traits_type::assign(__r->_M_refdata(), __n, __c); 
00178     }
00179       catch(...) 
00180     { 
00181       __r->_M_destroy(__a); 
00182       __throw_exception_again;
00183     }
00184       __r->_M_length = __n;
00185       __r->_M_refdata()[__n] = _Rep::_S_terminal;  
00186       return __r->_M_refdata();
00187     }
00188 
00189   template<typename _CharT, typename _Traits, typename _Alloc>
00190     basic_string<_CharT, _Traits, _Alloc>::
00191     basic_string(const basic_string& __str)
00192     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()),
00193          __str.get_allocator())
00194     { }
00195 
00196   template<typename _CharT, typename _Traits, typename _Alloc>
00197     basic_string<_CharT, _Traits, _Alloc>::
00198     basic_string(const _Alloc& __a)
00199     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
00200     { }
00201  
00202   template<typename _CharT, typename _Traits, typename _Alloc>
00203     basic_string<_CharT, _Traits, _Alloc>::
00204     basic_string(const basic_string& __str, size_type __pos, size_type __n)
00205     : _M_dataplus(_S_construct(__str._M_check(__pos), 
00206                    __str._M_fold(__pos, __n), _Alloc()), _Alloc())
00207     { }
00208 
00209   template<typename _CharT, typename _Traits, typename _Alloc>
00210     basic_string<_CharT, _Traits, _Alloc>::
00211     basic_string(const basic_string& __str, size_type __pos,
00212          size_type __n, const _Alloc& __a)
00213     : _M_dataplus(_S_construct(__str._M_check(__pos), 
00214                    __str._M_fold(__pos, __n), __a), __a)
00215     { }
00216 
00217   template<typename _CharT, typename _Traits, typename _Alloc>
00218     basic_string<_CharT, _Traits, _Alloc>::
00219     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
00220     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
00221     { }
00222 
00223   template<typename _CharT, typename _Traits, typename _Alloc>
00224     basic_string<_CharT, _Traits, _Alloc>::
00225     basic_string(const _CharT* __s, const _Alloc& __a)
00226     : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : 0, 
00227                    __a), __a)
00228     { }
00229 
00230   template<typename _CharT, typename _Traits, typename _Alloc>
00231     basic_string<_CharT, _Traits, _Alloc>::
00232     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
00233     : _M_dataplus(_S_construct(__n, __c, __a), __a)
00234     { }
00235  
00236   template<typename _CharT, typename _Traits, typename _Alloc>
00237     template<typename _InputIter>
00238     basic_string<_CharT, _Traits, _Alloc>::
00239     basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a)
00240     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
00241     { }
00242 
00243   template<typename _CharT, typename _Traits, typename _Alloc>
00244     basic_string<_CharT, _Traits, _Alloc>&
00245     basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str)
00246     {
00247       if (_M_rep() != __str._M_rep())
00248     {
00249       
00250       allocator_type __a = this->get_allocator();
00251       _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
00252       _M_rep()->_M_dispose(__a);
00253       _M_data(__tmp);
00254     }
00255       return *this;
00256     }
00257   
00258   template<typename _CharT, typename _Traits, typename _Alloc>
00259     void
00260     basic_string<_CharT, _Traits, _Alloc>::_Rep::
00261     _M_destroy(const _Alloc& __a) throw ()
00262     {
00263       size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT);
00264       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
00265     }
00266 
00267   template<typename _CharT, typename _Traits, typename _Alloc>
00268     void
00269     basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard()
00270     {
00271       if (_M_rep()->_M_is_shared()) 
00272     _M_mutate(0, 0, 0);
00273       _M_rep()->_M_set_leaked();
00274     }
00275 
00276   
00277   
00278   
00279   
00280   
00281   
00282   template<typename _CharT, typename _Traits, typename _Alloc>
00283     void
00284     basic_string<_CharT, _Traits, _Alloc>::
00285     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
00286     {
00287       size_type       __old_size = this->size();
00288       const size_type __new_size = __old_size + __len2 - __len1;
00289       const _CharT*        __src = _M_data()  + __pos + __len1;
00290       const size_type __how_much = __old_size - __pos - __len1;
00291       
00292       if (_M_rep()->_M_is_shared() || __new_size > capacity())
00293     {
00294       
00295       allocator_type __a = get_allocator();
00296       
00297       
00298       const size_type __pagesize = 4096;
00299       const size_type __malloc_header_size = 4 * sizeof (void*);
00300       
00301       const size_type __page_capacity = (__pagesize - __malloc_header_size
00302                          - sizeof(_Rep) - sizeof(_CharT)) 
00303                              / sizeof(_CharT);
00304       _Rep* __r;
00305       if (__new_size > capacity() && __new_size > __page_capacity)
00306         
00307         __r = _Rep::_S_create(__new_size > 2*capacity() ?
00308                   __new_size : 2*capacity(), __a);
00309       else
00310         __r = _Rep::_S_create(__new_size, __a);
00311       try 
00312         {
00313           if (__pos)
00314         traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
00315           if (__how_much)
00316         traits_type::copy(__r->_M_refdata() + __pos + __len2, 
00317                   __src, __how_much);
00318         }
00319       catch(...) 
00320         { 
00321           __r->_M_dispose(get_allocator()); 
00322           __throw_exception_again;
00323         }
00324       _M_rep()->_M_dispose(__a);
00325       _M_data(__r->_M_refdata());
00326       }
00327       else if (__how_much && __len1 != __len2)
00328     {
00329       
00330       traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
00331     }
00332       _M_rep()->_M_set_sharable();
00333       _M_rep()->_M_length = __new_size;
00334       _M_data()[__new_size] = _Rep::_S_terminal; 
00335     
00336     }
00337   
00338   template<typename _CharT, typename _Traits, typename _Alloc>
00339     void
00340     basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)
00341     {
00342       if (__res > this->capacity() || _M_rep()->_M_is_shared())
00343         {
00344       if (__res > this->max_size())
00345         __throw_length_error("basic_string::reserve");
00346       
00347       if (__res < this->size())
00348         __res = this->size();
00349       allocator_type __a = get_allocator();
00350       _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
00351       _M_rep()->_M_dispose(__a);
00352       _M_data(__tmp);
00353         }
00354     }
00355   
00356   template<typename _CharT, typename _Traits, typename _Alloc>
00357     void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s)
00358     {
00359       if (_M_rep()->_M_is_leaked()) 
00360     _M_rep()->_M_set_sharable();
00361       if (__s._M_rep()->_M_is_leaked()) 
00362     __s._M_rep()->_M_set_sharable();
00363       if (this->get_allocator() == __s.get_allocator())
00364     {
00365       _CharT* __tmp = _M_data();
00366       _M_data(__s._M_data());
00367       __s._M_data(__tmp);
00368     }
00369       
00370       else 
00371     {
00372       basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator());
00373       basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 
00374                   this->get_allocator());
00375       *this = __tmp2;
00376       __s = __tmp1;
00377     }
00378     }
00379 
00380   template<typename _CharT, typename _Traits, typename _Alloc>
00381     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
00382     basic_string<_CharT, _Traits, _Alloc>::_Rep::
00383     _S_create(size_t __capacity, const _Alloc& __alloc)
00384     {
00385       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00386 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00387       
00388       if (__capacity > _S_max_size)
00389 #else
00390       if (__capacity == npos)
00391 #endif
00392     __throw_length_error("basic_string::_S_create");
00393 
00394       
00395       
00396       
00397       size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00398 
00399       
00400       
00401       
00402       
00403       
00404       
00405       
00406       
00407       
00408       
00409       
00410       
00411 
00412       
00413       
00414       
00415       
00416       
00417       
00418       
00419       
00420       
00421       const size_t __pagesize = 4096; 
00422       const size_t __subpagesize = 128; 
00423       const size_t __malloc_header_size = 4 * sizeof (void*);
00424       if ((__size + __malloc_header_size) > __pagesize)
00425     {
00426       size_t __extra =
00427         (__pagesize - ((__size + __malloc_header_size) % __pagesize))
00428         % __pagesize;
00429       __capacity += __extra / sizeof(_CharT);
00430       __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00431     }
00432       else if (__size > __subpagesize)
00433     {
00434       size_t __extra =
00435         (__subpagesize - ((__size + __malloc_header_size) % __subpagesize))
00436         % __subpagesize;
00437       __capacity += __extra / sizeof(_CharT);
00438       __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00439     }
00440 
00441       
00442       
00443       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
00444       _Rep *__p = new (__place) _Rep;
00445       __p->_M_capacity = __capacity;
00446       __p->_M_set_sharable();  
00447       __p->_M_length = 0;
00448       return __p;
00449     }
00450 
00451   template<typename _CharT, typename _Traits, typename _Alloc>
00452     _CharT*
00453     basic_string<_CharT, _Traits, _Alloc>::_Rep::
00454     _M_clone(const _Alloc& __alloc, size_type __res)
00455     {
00456       
00457       const size_type __requested_cap = _M_length + __res;
00458       
00459       const size_type __pagesize = 4096;
00460       const size_type __malloc_header_size = 4 * sizeof (void*);
00461       
00462       const size_type __page_capacity =
00463         (__pagesize - __malloc_header_size - sizeof(_Rep) - sizeof(_CharT))
00464         / sizeof(_CharT);
00465       _Rep* __r;
00466       if (__requested_cap > _M_capacity && __requested_cap > __page_capacity)
00467         
00468         __r = _Rep::_S_create(__requested_cap > 2*_M_capacity ?
00469                               __requested_cap : 2*_M_capacity, __alloc);
00470       else
00471         __r = _Rep::_S_create(__requested_cap, __alloc);
00472       
00473       if (_M_length)
00474     {
00475       try 
00476         { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); }
00477       catch(...)  
00478         { 
00479           __r->_M_destroy(__alloc); 
00480           __throw_exception_again;
00481         }
00482     }
00483       __r->_M_length = _M_length;
00484       return __r->_M_refdata();
00485     }
00486   
00487   template<typename _CharT, typename _Traits, typename _Alloc>
00488     void
00489     basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
00490     {
00491       if (__n > max_size())
00492     __throw_length_error("basic_string::resize");
00493       size_type __size = this->size();
00494       if (__size < __n)
00495     this->append(__n - __size, __c);
00496       else if (__n < __size)
00497     this->erase(__n);
00498       
00499     }
00500   
00501   
00502   
00503   
00504   
00505   
00506   
00507   
00508   template<typename _CharT, typename _Traits, typename _Alloc>
00509     template<typename _InputIter>
00510       basic_string<_CharT, _Traits, _Alloc>&
00511       basic_string<_CharT, _Traits, _Alloc>::
00512       _M_replace(iterator __i1, iterator __i2, _InputIter __k1, 
00513          _InputIter __k2, input_iterator_tag)
00514       {
00515     
00516     basic_string __s(__k1, __k2);
00517     return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend());
00518       }
00519 
00520   
00521   
00522   
00523   
00524   
00525   template<typename _CharT, typename _Traits, typename _Alloc>
00526     template<typename _ForwardIter>
00527       basic_string<_CharT, _Traits, _Alloc>&
00528       basic_string<_CharT, _Traits, _Alloc>::
00529       _M_replace_safe(iterator __i1, iterator __i2, _ForwardIter __k1, 
00530               _ForwardIter __k2)
00531       {
00532     size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
00533     size_type __dold = __i2 - __i1;
00534     size_type __dmax = this->max_size();
00535 
00536     if (__dmax <= __dnew)
00537       __throw_length_error("basic_string::_M_replace");
00538     size_type __off = __i1 - _M_ibegin();
00539     _M_mutate(__off, __dold, __dnew);
00540 
00541     
00542         if (__dnew)
00543       _S_copy_chars(_M_data() + __off, __k1, __k2);
00544 
00545     return *this;
00546       }
00547 
00548   template<typename _CharT, typename _Traits, typename _Alloc>
00549     basic_string<_CharT, _Traits, _Alloc>&
00550     basic_string<_CharT, _Traits, _Alloc>::
00551     replace(size_type __pos1, size_type __n1, const basic_string& __str,
00552         size_type __pos2, size_type __n2)
00553     {
00554       const size_type __strsize = __str.size();
00555       if (__pos2 > __strsize)
00556     __throw_out_of_range("basic_string::replace");
00557       const bool __testn2 = __n2 < __strsize - __pos2;
00558       const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;
00559       return this->replace(__pos1, __n1,
00560                __str._M_data() + __pos2, __foldn2);      
00561     }
00562 
00563   template<typename _CharT, typename _Traits, typename _Alloc>
00564     basic_string<_CharT, _Traits, _Alloc>&
00565     basic_string<_CharT, _Traits, _Alloc>::
00566     append(const basic_string& __str)
00567     {
00568       
00569       
00570       
00571       size_type __size = __str.size();
00572       size_type __len = __size + this->size();
00573       if (__len > this->capacity())
00574     this->reserve(__len);
00575       return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
00576                  __str._M_iend());
00577     }
00578 
00579   template<typename _CharT, typename _Traits, typename _Alloc>
00580     basic_string<_CharT, _Traits, _Alloc>&
00581     basic_string<_CharT, _Traits, _Alloc>::
00582     append(const basic_string& __str, size_type __pos, size_type __n)
00583     {
00584       
00585       
00586       
00587       size_type __len = min(__str.size() - __pos, __n) + this->size();
00588       if (__len > this->capacity())
00589     this->reserve(__len);
00590       return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),
00591                  __str._M_fold(__pos, __n));
00592     }
00593 
00594   template<typename _CharT, typename _Traits, typename _Alloc>
00595     basic_string<_CharT, _Traits, _Alloc>&
00596     basic_string<_CharT, _Traits, _Alloc>::
00597     append(const _CharT* __s, size_type __n)
00598     {
00599       size_type __len = __n + this->size();
00600       if (__len > this->capacity())
00601     this->reserve(__len);
00602       return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n);
00603     }
00604 
00605   template<typename _CharT, typename _Traits, typename _Alloc>
00606     basic_string<_CharT, _Traits, _Alloc>&
00607     basic_string<_CharT, _Traits, _Alloc>::
00608     append(size_type __n, _CharT __c)
00609     {
00610       size_type __len = __n + this->size();
00611       if (__len > this->capacity())
00612     this->reserve(__len);
00613        return this->replace(_M_iend(), _M_iend(), __n, __c);
00614     }
00615 
00616   template<typename _CharT, typename _Traits, typename _Alloc>
00617     basic_string<_CharT, _Traits, _Alloc>
00618     operator+(const _CharT* __lhs,
00619           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00620     {
00621       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00622       typedef typename __string_type::size_type   __size_type;
00623       __size_type __len = _Traits::length(__lhs);
00624       __string_type __str;
00625       __str.reserve(__len + __rhs.size());
00626       __str.append(__lhs, __lhs + __len);
00627       __str.append(__rhs);
00628       return __str;
00629     }
00630 
00631   template<typename _CharT, typename _Traits, typename _Alloc>
00632     basic_string<_CharT, _Traits, _Alloc>
00633     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00634     {
00635       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00636       typedef typename __string_type::size_type   __size_type;
00637       __string_type __str;
00638       __size_type __len = __rhs.size();
00639       __str.reserve(__len + 1);
00640       __str.append(__size_type(1), __lhs);
00641       __str.append(__rhs);
00642       return __str;
00643     }
00644 
00645   template<typename _CharT, typename _Traits, typename _Alloc>
00646     basic_string<_CharT, _Traits, _Alloc>&
00647     basic_string<_CharT, _Traits, _Alloc>::
00648     replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c)
00649     {
00650       size_type __n1 = __i2 - __i1;
00651       size_type __off1 = __i1 - _M_ibegin();
00652       if (max_size() - (this->size() - __n1) <= __n2)
00653     __throw_length_error("basic_string::replace");
00654       _M_mutate (__off1, __n1, __n2);
00655       
00656       if (__n2)
00657     traits_type::assign(_M_data() + __off1, __n2, __c);
00658       return *this;
00659     }
00660   
00661   template<typename _CharT, typename _Traits, typename _Alloc>
00662     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00663     basic_string<_CharT, _Traits, _Alloc>::
00664     copy(_CharT* __s, size_type __n, size_type __pos) const
00665     {
00666       if (__pos > this->size())
00667     __throw_out_of_range("basic_string::copy");
00668       
00669       if (__n > this->size() - __pos)
00670     __n = this->size() - __pos;
00671       
00672       traits_type::copy(__s, _M_data() + __pos, __n);
00673       
00674       return __n;
00675     }
00676 
00677   template<typename _CharT, typename _Traits, typename _Alloc>
00678     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00679     basic_string<_CharT, _Traits, _Alloc>::
00680     find(const _CharT* __s, size_type __pos, size_type __n) const
00681     {
00682       size_type __size = this->size();
00683       size_t __xpos = __pos;
00684       const _CharT* __data = _M_data();
00685       for (; __xpos + __n <= __size; ++__xpos)
00686     if (traits_type::compare(__data + __xpos, __s, __n) == 0)
00687       return __xpos;
00688       return npos;
00689     }
00690 
00691   template<typename _CharT, typename _Traits, typename _Alloc>
00692     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00693     basic_string<_CharT, _Traits, _Alloc>::
00694     find(_CharT __c, size_type __pos) const
00695     {
00696       size_type __size = this->size();
00697       size_type __ret = npos;
00698       if (__pos < __size)
00699     {
00700       const _CharT* __data = _M_data();
00701       size_type __n = __size - __pos;
00702       const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
00703       if (__p)
00704         __ret = __p - __data;
00705     }
00706       return __ret;
00707     }
00708 
00709 
00710   template<typename _CharT, typename _Traits, typename _Alloc>
00711     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00712     basic_string<_CharT, _Traits, _Alloc>::
00713     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00714     {
00715       size_type __size = this->size();
00716       if (__n <= __size)
00717     {
00718       __pos = std::min(__size - __n, __pos);
00719       const _CharT* __data = _M_data();
00720       do 
00721         {
00722           if (traits_type::compare(__data + __pos, __s, __n) == 0)
00723         return __pos;
00724         } 
00725       while (__pos-- > 0);
00726     }
00727       return npos;
00728     }
00729   
00730   template<typename _CharT, typename _Traits, typename _Alloc>
00731     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00732     basic_string<_CharT, _Traits, _Alloc>::
00733     rfind(_CharT __c, size_type __pos) const
00734     {
00735       size_type __size = this->size();
00736       if (__size)
00737     {
00738       size_t __xpos = __size - 1;
00739       if (__xpos > __pos)
00740         __xpos = __pos;
00741       
00742       for (++__xpos; __xpos-- > 0; )
00743         if (traits_type::eq(_M_data()[__xpos], __c))
00744           return __xpos;
00745     }
00746       return npos;
00747     }
00748   
00749   template<typename _CharT, typename _Traits, typename _Alloc>
00750     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00751     basic_string<_CharT, _Traits, _Alloc>::
00752     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00753     {
00754       for (; __n && __pos < this->size(); ++__pos)
00755     {
00756       const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
00757       if (__p)
00758         return __pos;
00759     }
00760       return npos;
00761     }
00762  
00763   template<typename _CharT, typename _Traits, typename _Alloc>
00764     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00765     basic_string<_CharT, _Traits, _Alloc>::
00766     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00767     {
00768       size_type __size = this->size();
00769       if (__size && __n)
00770     { 
00771       if (--__size > __pos) 
00772         __size = __pos;
00773       do
00774         {
00775           if (traits_type::find(__s, __n, _M_data()[__size]))
00776         return __size;
00777         } 
00778       while (__size-- != 0);
00779     }
00780       return npos;
00781     }
00782   
00783   template<typename _CharT, typename _Traits, typename _Alloc>
00784     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00785     basic_string<_CharT, _Traits, _Alloc>::
00786     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00787     {
00788       size_t __xpos = __pos;
00789       for (; __xpos < this->size(); ++__xpos)
00790     if (!traits_type::find(__s, __n, _M_data()[__xpos]))
00791       return __xpos;
00792       return npos;
00793     }
00794 
00795   template<typename _CharT, typename _Traits, typename _Alloc>
00796     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00797     basic_string<_CharT, _Traits, _Alloc>::
00798     find_first_not_of(_CharT __c, size_type __pos) const
00799     {
00800       size_t __xpos = __pos;
00801       for (; __xpos < this->size(); ++__xpos)
00802     if (!traits_type::eq(_M_data()[__xpos], __c))
00803       return __xpos;
00804       return npos;
00805     }
00806 
00807   template<typename _CharT, typename _Traits, typename _Alloc>
00808     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00809     basic_string<_CharT, _Traits, _Alloc>::
00810     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00811     {
00812       size_type __size = this->size();
00813       if (__size)
00814     { 
00815       if (--__size > __pos) 
00816         __size = __pos;
00817       do
00818         {
00819           if (!traits_type::find(__s, __n, _M_data()[__size]))
00820         return __size;
00821         } 
00822       while (__size--);
00823     }
00824       return npos;
00825     }
00826 
00827   template<typename _CharT, typename _Traits, typename _Alloc>
00828     typename basic_string<_CharT, _Traits, _Alloc>::size_type
00829     basic_string<_CharT, _Traits, _Alloc>::
00830     find_last_not_of(_CharT __c, size_type __pos) const
00831     {
00832       size_type __size = this->size();
00833       if (__size)
00834     { 
00835       if (--__size > __pos) 
00836         __size = __pos;
00837       do
00838         {
00839           if (!traits_type::eq(_M_data()[__size], __c))
00840         return __size;
00841         } 
00842       while (__size--);
00843     }
00844       return npos;
00845     }
00846   
00847   template<typename _CharT, typename _Traits, typename _Alloc>
00848     int
00849     basic_string<_CharT, _Traits, _Alloc>::
00850     compare(size_type __pos, size_type __n, const basic_string& __str) const
00851     {
00852       size_type __size = this->size();
00853       size_type __osize = __str.size();
00854       if (__pos > __size)
00855     __throw_out_of_range("basic_string::compare");
00856       
00857       size_type __rsize= min(__size - __pos, __n);
00858       size_type __len = min(__rsize, __osize);
00859       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
00860       if (!__r)
00861     __r = __rsize - __osize;
00862       return __r;
00863     }
00864 
00865   template<typename _CharT, typename _Traits, typename _Alloc>
00866     int
00867     basic_string<_CharT, _Traits, _Alloc>::
00868     compare(size_type __pos1, size_type __n1, const basic_string& __str,
00869         size_type __pos2, size_type __n2) const
00870     {
00871       size_type __size = this->size();
00872       size_type __osize = __str.size();
00873       if (__pos1 > __size || __pos2 > __osize)
00874     __throw_out_of_range("basic_string::compare");
00875       
00876       size_type __rsize = min(__size - __pos1, __n1);
00877       size_type __rosize = min(__osize - __pos2, __n2);
00878       size_type __len = min(__rsize, __rosize);
00879       int __r = traits_type::compare(_M_data() + __pos1, 
00880                      __str.data() + __pos2, __len);
00881       if (!__r)
00882     __r = __rsize - __rosize;
00883       return __r;
00884     }
00885 
00886 
00887   template<typename _CharT, typename _Traits, typename _Alloc>
00888     int
00889     basic_string<_CharT, _Traits, _Alloc>::
00890     compare(const _CharT* __s) const
00891     {
00892       size_type __size = this->size();
00893       int __r = traits_type::compare(_M_data(), __s, __size);
00894       if (!__r)
00895     __r = __size - traits_type::length(__s);
00896       return __r;
00897     }
00898 
00899 
00900   template<typename _CharT, typename _Traits, typename _Alloc>
00901     int
00902     basic_string <_CharT, _Traits, _Alloc>::
00903     compare(size_type __pos, size_type __n1, const _CharT* __s) const
00904     {
00905       size_type __size = this->size();
00906       if (__pos > __size)
00907     __throw_out_of_range("basic_string::compare");
00908       
00909       size_type __osize = traits_type::length(__s);
00910       size_type __rsize = min(__size - __pos, __n1);
00911       size_type __len = min(__rsize, __osize);
00912       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
00913       if (!__r)
00914     __r = __rsize - __osize;
00915       return __r;
00916     }
00917 
00918   template<typename _CharT, typename _Traits, typename _Alloc>
00919     int
00920     basic_string <_CharT, _Traits, _Alloc>::
00921     compare(size_type __pos, size_type __n1, const _CharT* __s, 
00922         size_type __n2) const
00923     {
00924       size_type __size = this->size();
00925       if (__pos > __size)
00926     __throw_out_of_range("basic_string::compare");
00927       
00928       size_type __osize = min(traits_type::length(__s), __n2);
00929       size_type __rsize = min(__size - __pos, __n1);
00930       size_type __len = min(__rsize, __osize);
00931       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
00932       if (!__r)
00933     __r = __rsize - __osize;
00934       return __r;
00935     }
00936 
00937   template <class _CharT, class _Traits, class _Alloc>
00938     void
00939     _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str,
00940            _CharT* __buf, typename _Alloc::size_type __bufsiz)
00941     {
00942       typedef typename _Alloc::size_type size_type;
00943       size_type __strsize = __str.size();
00944       size_type __bytes = min(__strsize, __bufsiz - 1);
00945       _Traits::copy(__buf, __str.data(), __bytes);
00946       __buf[__bytes] = _CharT();
00947     }
00948 
00949   
00950   
00951   
00952   extern template class basic_string<char>;
00953   extern template 
00954     basic_istream<char>& 
00955     operator>>(basic_istream<char>&, string&);
00956   extern template 
00957     basic_ostream<char>& 
00958     operator<<(basic_ostream<char>&, const string&);
00959   extern template 
00960     basic_istream<char>& 
00961     getline(basic_istream<char>&, string&, char);
00962   extern template 
00963     basic_istream<char>& 
00964     getline(basic_istream<char>&, string&);
00965 
00966   extern template class basic_string<wchar_t>;
00967   extern template 
00968     basic_istream<wchar_t>& 
00969     operator>>(basic_istream<wchar_t>&, wstring&);
00970   extern template 
00971     basic_ostream<wchar_t>& 
00972     operator<<(basic_ostream<wchar_t>&, const wstring&);
00973   extern template 
00974     basic_istream<wchar_t>& 
00975     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
00976   extern template 
00977     basic_istream<wchar_t>& 
00978     getline(basic_istream<wchar_t>&, wstring&);
00979 } 
00980 
00981 #endif