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