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