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 _BASIC_STRING_H
00041 #define _BASIC_STRING_H 1
00042 
00043 #pragma GCC system_header
00044 
00045 #include <bits/atomicity.h>
00046 #include <debug/debug.h>
00047 
00048 namespace std
00049 {
00108   
00109   template<typename _CharT, typename _Traits, typename _Alloc>
00110     class basic_string
00111     {
00112       typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
00113 
00114       
00115     public:
00116       typedef _Traits                       traits_type;
00117       typedef typename _Traits::char_type           value_type;
00118       typedef _Alloc                        allocator_type;
00119       typedef typename _CharT_alloc_type::size_type     size_type;
00120       typedef typename _CharT_alloc_type::difference_type   difference_type;
00121       typedef typename _CharT_alloc_type::reference     reference;
00122       typedef typename _CharT_alloc_type::const_reference   const_reference;
00123       typedef typename _CharT_alloc_type::pointer       pointer;
00124       typedef typename _CharT_alloc_type::const_pointer     const_pointer;
00125       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
00126       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
00127                                                             const_iterator;
00128       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00129       typedef std::reverse_iterator<iterator>           reverse_iterator;
00130 
00131     private:
00132       
00133       
00134       
00135       
00136       
00137       
00138       
00139       
00140       
00141       
00142       
00143       
00144       
00145 
00146       struct _Rep_base
00147       {
00148     size_type       _M_length;
00149     size_type       _M_capacity;
00150     _Atomic_word        _M_refcount;
00151       };
00152 
00153       struct _Rep : _Rep_base
00154       {
00155     
00156     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
00157 
00158     
00159 
00160     
00161     
00162     
00163     
00164     
00165     
00166     
00167     
00168     
00169     
00170     
00171     static const size_type  _S_max_size;
00172     static const _CharT _S_terminal;
00173 
00174     
00175         
00176         static size_type _S_empty_rep_storage[];
00177 
00178         static _Rep&
00179         _S_empty_rep()
00180         {
00181       void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
00182       return *reinterpret_cast<_Rep*>(__p);
00183     }
00184 
00185         bool
00186     _M_is_leaked() const
00187         { return this->_M_refcount < 0; }
00188 
00189         bool
00190     _M_is_shared() const
00191         { return this->_M_refcount > 0; }
00192 
00193         void
00194     _M_set_leaked()
00195         { this->_M_refcount = -1; }
00196 
00197         void
00198     _M_set_sharable()
00199         { this->_M_refcount = 0; }
00200 
00201     void
00202     _M_set_length_and_sharable(size_type __n)
00203     { 
00204       this->_M_set_sharable();  
00205       this->_M_length = __n;
00206       traits_type::assign(this->_M_refdata()[__n], _S_terminal);
00207       
00208       
00209     }
00210 
00211     _CharT*
00212     _M_refdata() throw()
00213     { return reinterpret_cast<_CharT*>(this + 1); }
00214 
00215     _CharT*
00216     _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
00217     {
00218       return (!_M_is_leaked() && __alloc1 == __alloc2)
00219               ? _M_refcopy() : _M_clone(__alloc1);
00220     }
00221 
00222     
00223     static _Rep*
00224     _S_create(size_type, size_type, const _Alloc&);
00225 
00226     void
00227     _M_dispose(const _Alloc& __a)
00228     {
00229 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
00230       if (__builtin_expect(this != &_S_empty_rep(), false))
00231 #endif
00232         if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0)
00233           _M_destroy(__a);
00234     }  
00235 
00236     void
00237     _M_destroy(const _Alloc&) throw();
00238 
00239     _CharT*
00240     _M_refcopy() throw()
00241     {
00242 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
00243       if (__builtin_expect(this != &_S_empty_rep(), false))
00244 #endif
00245             __gnu_cxx::__atomic_add(&this->_M_refcount, 1);
00246       return _M_refdata();
00247     }  
00248 
00249     _CharT*
00250     _M_clone(const _Alloc&, size_type __res = 0);
00251       };
00252 
00253       
00254       struct _Alloc_hider : _Alloc
00255       {
00256     _Alloc_hider(_CharT* __dat, const _Alloc& __a)
00257     : _Alloc(__a), _M_p(__dat) { }
00258 
00259     _CharT* _M_p; 
00260       };
00261 
00262     public:
00263       
00264       
00265       
00267       static const size_type    npos = static_cast<size_type>(-1);
00268 
00269     private:
00270       
00271       mutable _Alloc_hider  _M_dataplus;
00272 
00273       _CharT*
00274       _M_data() const
00275       { return  _M_dataplus._M_p; }
00276 
00277       _CharT*
00278       _M_data(_CharT* __p)
00279       { return (_M_dataplus._M_p = __p); }
00280 
00281       _Rep*
00282       _M_rep() const
00283       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
00284 
00285       
00286       
00287       iterator
00288       _M_ibegin() const
00289       { return iterator(_M_data()); }
00290 
00291       iterator
00292       _M_iend() const
00293       { return iterator(_M_data() + this->size()); }
00294 
00295       void
00296       _M_leak()    
00297       {
00298     if (!_M_rep()->_M_is_leaked())
00299       _M_leak_hard();
00300       }
00301 
00302       size_type
00303       _M_check(size_type __pos, const char* __s) const
00304       {
00305     if (__pos > this->size())
00306       __throw_out_of_range(__N(__s));
00307     return __pos;
00308       }
00309 
00310       void
00311       _M_check_length(size_type __n1, size_type __n2, const char* __s) const
00312       {
00313     if (this->max_size() - (this->size() - __n1) < __n2)
00314       __throw_length_error(__N(__s));
00315       }
00316 
00317       
00318       size_type
00319       _M_limit(size_type __pos, size_type __off) const
00320       {
00321     const bool __testoff =  __off < this->size() - __pos;
00322     return __testoff ? __off : this->size() - __pos;
00323       }
00324 
00325       
00326       bool
00327       _M_disjunct(const _CharT* __s) const
00328       {
00329     return (less<const _CharT*>()(__s, _M_data())
00330         || less<const _CharT*>()(_M_data() + this->size(), __s));
00331       }
00332 
00333       
00334       
00335       static void
00336       _M_copy(_CharT* __d, const _CharT* __s, size_type __n)
00337       {
00338     if (__n == 1)
00339       traits_type::assign(*__d, *__s);
00340     else
00341       traits_type::copy(__d, __s, __n);
00342       }
00343 
00344       static void
00345       _M_move(_CharT* __d, const _CharT* __s, size_type __n)
00346       {
00347     if (__n == 1)
00348       traits_type::assign(*__d, *__s);
00349     else
00350       traits_type::move(__d, __s, __n);   
00351       }
00352 
00353       static void
00354       _M_assign(_CharT* __d, size_type __n, _CharT __c)
00355       {
00356     if (__n == 1)
00357       traits_type::assign(*__d, __c);
00358     else
00359       traits_type::assign(__d, __n, __c);     
00360       }
00361 
00362       
00363       
00364       template<class _Iterator>
00365         static void
00366         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00367         {
00368       for (; __k1 != __k2; ++__k1, ++__p)
00369         traits_type::assign(*__p, *__k1); 
00370     }
00371 
00372       static void
00373       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
00374       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00375 
00376       static void
00377       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
00378       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00379 
00380       static void
00381       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00382       { _M_copy(__p, __k1, __k2 - __k1); }
00383 
00384       static void
00385       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00386       { _M_copy(__p, __k1, __k2 - __k1); }
00387 
00388       void
00389       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
00390 
00391       void
00392       _M_leak_hard();
00393 
00394       static _Rep&
00395       _S_empty_rep()
00396       { return _Rep::_S_empty_rep(); }
00397 
00398     public:
00399       
00400       
00401       
00402 
00406       inline
00407       basic_string();
00408 
00412       explicit
00413       basic_string(const _Alloc& __a);
00414 
00415       
00420       basic_string(const basic_string& __str);
00427       basic_string(const basic_string& __str, size_type __pos,
00428            size_type __n = npos);
00436       basic_string(const basic_string& __str, size_type __pos,
00437            size_type __n, const _Alloc& __a);
00438 
00448       basic_string(const _CharT* __s, size_type __n,
00449            const _Alloc& __a = _Alloc());
00455       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
00462       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
00463 
00470       template<class _InputIterator>
00471         basic_string(_InputIterator __beg, _InputIterator __end,
00472              const _Alloc& __a = _Alloc());
00473 
00477       ~basic_string()
00478       { _M_rep()->_M_dispose(this->get_allocator()); }
00479 
00484       basic_string&
00485       operator=(const basic_string& __str) 
00486       { return this->assign(__str); }
00487 
00492       basic_string&
00493       operator=(const _CharT* __s) 
00494       { return this->assign(__s); }
00495 
00503       basic_string&
00504       operator=(_CharT __c) 
00505       { 
00506     this->assign(1, __c); 
00507     return *this;
00508       }
00509 
00510       
00515       iterator
00516       begin()
00517       {
00518     _M_leak();
00519     return iterator(_M_data());
00520       }
00521 
00526       const_iterator
00527       begin() const
00528       { return const_iterator(_M_data()); }
00529 
00534       iterator
00535       end()
00536       {
00537     _M_leak();
00538     return iterator(_M_data() + this->size());
00539       }
00540 
00545       const_iterator
00546       end() const
00547       { return const_iterator(_M_data() + this->size()); }
00548 
00554       reverse_iterator
00555       rbegin()
00556       { return reverse_iterator(this->end()); }
00557 
00563       const_reverse_iterator
00564       rbegin() const
00565       { return const_reverse_iterator(this->end()); }
00566 
00572       reverse_iterator
00573       rend()
00574       { return reverse_iterator(this->begin()); }
00575 
00581       const_reverse_iterator
00582       rend() const
00583       { return const_reverse_iterator(this->begin()); }
00584 
00585     public:
00586       
00589       size_type
00590       size() const
00591       { return _M_rep()->_M_length; }
00592 
00595       size_type
00596       length() const
00597       { return _M_rep()->_M_length; }
00598 
00600       size_type
00601       max_size() const
00602       { return _Rep::_S_max_size; }
00603 
00614       void
00615       resize(size_type __n, _CharT __c);
00616 
00627       void
00628       resize(size_type __n)
00629       { this->resize(__n, _CharT()); }
00630 
00635       size_type
00636       capacity() const
00637       { return _M_rep()->_M_capacity; }
00638 
00656       void
00657       reserve(size_type __res_arg = 0);
00658 
00662       void
00663       clear()
00664       { _M_mutate(0, this->size(), 0); }
00665 
00669       bool
00670       empty() const
00671       { return this->size() == 0; }
00672 
00673       
00684       const_reference
00685       operator[] (size_type __pos) const
00686       {
00687     _GLIBCXX_DEBUG_ASSERT(__pos <= size());
00688     return _M_data()[__pos];
00689       }
00690 
00701       reference
00702       operator[](size_type __pos)
00703       {
00704         
00705     _GLIBCXX_DEBUG_ASSERT(__pos <= size());
00706         
00707     _GLIBCXX_DEBUG_PEDASSERT(__pos < size());
00708     _M_leak();
00709     return _M_data()[__pos];
00710       }
00711 
00722       const_reference
00723       at(size_type __n) const
00724       {
00725     if (__n >= this->size())
00726       __throw_out_of_range(__N("basic_string::at"));
00727     return _M_data()[__n];
00728       }
00729 
00741       reference
00742       at(size_type __n)
00743       {
00744     if (__n >= size())
00745       __throw_out_of_range(__N("basic_string::at"));
00746     _M_leak();
00747     return _M_data()[__n];
00748       }
00749 
00750       
00756       basic_string&
00757       operator+=(const basic_string& __str)
00758       { return this->append(__str); }
00759 
00765       basic_string&
00766       operator+=(const _CharT* __s)
00767       { return this->append(__s); }
00768 
00774       basic_string&
00775       operator+=(_CharT __c)
00776       { 
00777     this->push_back(__c);
00778     return *this;
00779       }
00780 
00786       basic_string&
00787       append(const basic_string& __str);
00788 
00801       basic_string&
00802       append(const basic_string& __str, size_type __pos, size_type __n);
00803 
00810       basic_string&
00811       append(const _CharT* __s, size_type __n);
00812 
00818       basic_string&
00819       append(const _CharT* __s)
00820       {
00821     __glibcxx_requires_string(__s);
00822     return this->append(__s, traits_type::length(__s));
00823       }
00824 
00833       basic_string&
00834       append(size_type __n, _CharT __c);
00835 
00844       template<class _InputIterator>
00845         basic_string&
00846         append(_InputIterator __first, _InputIterator __last)
00847         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
00848 
00853       void
00854       push_back(_CharT __c)
00855       { 
00856     const size_type __len = 1 + this->size();
00857     if (__len > this->capacity() || _M_rep()->_M_is_shared())
00858       this->reserve(__len);
00859     traits_type::assign(_M_data()[this->size()], __c);
00860     _M_rep()->_M_set_length_and_sharable(__len);
00861       }
00862 
00868       basic_string&
00869       assign(const basic_string& __str);
00870 
00883       basic_string&
00884       assign(const basic_string& __str, size_type __pos, size_type __n)
00885       { return this->assign(__str._M_data()
00886                 + __str._M_check(__pos, "basic_string::assign"),
00887                 __str._M_limit(__pos, __n)); }
00888 
00899       basic_string&
00900       assign(const _CharT* __s, size_type __n);
00901 
00911       basic_string&
00912       assign(const _CharT* __s)
00913       {
00914     __glibcxx_requires_string(__s);
00915     return this->assign(__s, traits_type::length(__s));
00916       }
00917 
00927       basic_string&
00928       assign(size_type __n, _CharT __c)
00929       { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
00930 
00939       template<class _InputIterator>
00940         basic_string&
00941         assign(_InputIterator __first, _InputIterator __last)
00942         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
00943 
00956       void
00957       insert(iterator __p, size_type __n, _CharT __c)
00958       { this->replace(__p, __p, __n, __c);  }
00959 
00971       template<class _InputIterator>
00972         void
00973         insert(iterator __p, _InputIterator __beg, _InputIterator __end)
00974         { this->replace(__p, __p, __beg, __end); }
00975 
00987       basic_string&
00988       insert(size_type __pos1, const basic_string& __str)
00989       { return this->insert(__pos1, __str, size_type(0), __str.size()); }
00990 
01009       basic_string&
01010       insert(size_type __pos1, const basic_string& __str,
01011          size_type __pos2, size_type __n)
01012       { return this->insert(__pos1, __str._M_data()
01013                 + __str._M_check(__pos2, "basic_string::insert"),
01014                 __str._M_limit(__pos2, __n)); }
01015 
01032       basic_string&
01033       insert(size_type __pos, const _CharT* __s, size_type __n);
01034 
01050       basic_string&
01051       insert(size_type __pos, const _CharT* __s)
01052       {
01053     __glibcxx_requires_string(__s);
01054     return this->insert(__pos, __s, traits_type::length(__s));
01055       }
01056 
01073       basic_string&
01074       insert(size_type __pos, size_type __n, _CharT __c)
01075       { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
01076                   size_type(0), __n, __c); }
01077 
01090       iterator
01091       insert(iterator __p, _CharT __c)
01092       {
01093     _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
01094     const size_type __pos = __p - _M_ibegin();
01095     _M_replace_aux(__pos, size_type(0), size_type(1), __c);
01096     _M_rep()->_M_set_leaked();
01097     return this->_M_ibegin() + __pos;
01098       }
01099 
01114       basic_string&
01115       erase(size_type __pos = 0, size_type __n = npos)
01116       { 
01117     _M_mutate(_M_check(__pos, "basic_string::erase"),
01118           _M_limit(__pos, __n), size_type(0));
01119     return *this;
01120       }
01121 
01130       iterator
01131       erase(iterator __position)
01132       {
01133     _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
01134                  && __position < _M_iend());
01135     const size_type __pos = __position - _M_ibegin();
01136     _M_mutate(__pos, size_type(1), size_type(0));
01137     _M_rep()->_M_set_leaked();
01138     return _M_ibegin() + __pos;
01139       }
01140 
01150       iterator
01151       erase(iterator __first, iterator __last)
01152       {
01153     _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
01154                  && __last <= _M_iend());
01155         const size_type __pos = __first - _M_ibegin();
01156     _M_mutate(__pos, __last - __first, size_type(0));
01157     _M_rep()->_M_set_leaked();
01158     return _M_ibegin() + __pos;
01159       }
01160 
01177       basic_string&
01178       replace(size_type __pos, size_type __n, const basic_string& __str)
01179       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
01180 
01199       basic_string&
01200       replace(size_type __pos1, size_type __n1, const basic_string& __str,
01201           size_type __pos2, size_type __n2)
01202       { return this->replace(__pos1, __n1, __str._M_data()
01203                  + __str._M_check(__pos2, "basic_string::replace"),
01204                  __str._M_limit(__pos2, __n2)); }
01205 
01223       basic_string&
01224       replace(size_type __pos, size_type __n1, const _CharT* __s,
01225           size_type __n2);
01226 
01242       basic_string&
01243       replace(size_type __pos, size_type __n1, const _CharT* __s)
01244       {
01245     __glibcxx_requires_string(__s);
01246     return this->replace(__pos, __n1, __s, traits_type::length(__s));
01247       }
01248 
01265       basic_string&
01266       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
01267       { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
01268                   _M_limit(__pos, __n1), __n2, __c); }
01269 
01283       basic_string&
01284       replace(iterator __i1, iterator __i2, const basic_string& __str)
01285       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
01286 
01301       basic_string&
01302       replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
01303       {
01304     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01305                  && __i2 <= _M_iend());
01306     return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
01307       }
01308 
01322       basic_string&
01323       replace(iterator __i1, iterator __i2, const _CharT* __s)
01324       {
01325     __glibcxx_requires_string(__s);
01326     return this->replace(__i1, __i2, __s, traits_type::length(__s));
01327       }
01328 
01343       basic_string&
01344       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
01345       {
01346     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01347                  && __i2 <= _M_iend());
01348     return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
01349       }
01350 
01365       template<class _InputIterator>
01366         basic_string&
01367         replace(iterator __i1, iterator __i2,
01368         _InputIterator __k1, _InputIterator __k2)
01369         {
01370       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01371                    && __i2 <= _M_iend());
01372       __glibcxx_requires_valid_range(__k1, __k2);
01373       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
01374       return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
01375     }
01376 
01377       
01378       
01379       basic_string&
01380       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
01381       {
01382     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01383                  && __i2 <= _M_iend());
01384     __glibcxx_requires_valid_range(__k1, __k2);
01385     return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01386                  __k1, __k2 - __k1);
01387       }
01388 
01389       basic_string&
01390       replace(iterator __i1, iterator __i2,
01391           const _CharT* __k1, const _CharT* __k2)
01392       {
01393     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01394                  && __i2 <= _M_iend());
01395     __glibcxx_requires_valid_range(__k1, __k2);
01396     return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01397                  __k1, __k2 - __k1);
01398       }
01399 
01400       basic_string&
01401       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
01402       {
01403     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01404                  && __i2 <= _M_iend());
01405     __glibcxx_requires_valid_range(__k1, __k2);
01406     return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01407                  __k1.base(), __k2 - __k1);
01408       }
01409 
01410       basic_string&
01411       replace(iterator __i1, iterator __i2,
01412           const_iterator __k1, const_iterator __k2)
01413       {
01414     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01415                  && __i2 <= _M_iend());
01416     __glibcxx_requires_valid_range(__k1, __k2);
01417     return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01418                  __k1.base(), __k2 - __k1);
01419       }
01420       
01421     private:
01422       template<class _Integer>
01423     basic_string&
01424     _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
01425                 _Integer __val, __true_type)
01426         { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
01427 
01428       template<class _InputIterator>
01429     basic_string&
01430     _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
01431                 _InputIterator __k2, __false_type);
01432 
01433       basic_string&
01434       _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
01435              _CharT __c);
01436 
01437       basic_string&
01438       _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
01439               size_type __n2);
01440 
01441       
01442       
01443       template<class _InIterator>
01444         static _CharT*
01445         _S_construct_aux(_InIterator __beg, _InIterator __end,
01446              const _Alloc& __a, __false_type)
01447     {
01448           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
01449           return _S_construct(__beg, __end, __a, _Tag());
01450     }
01451 
01452       template<class _InIterator>
01453         static _CharT*
01454         _S_construct_aux(_InIterator __beg, _InIterator __end,
01455              const _Alloc& __a, __true_type)
01456     { return _S_construct(static_cast<size_type>(__beg),
01457                   static_cast<value_type>(__end), __a); }
01458 
01459       template<class _InIterator>
01460         static _CharT*
01461         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
01462     {
01463       typedef typename std::__is_integer<_InIterator>::__type _Integral;
01464       return _S_construct_aux(__beg, __end, __a, _Integral());
01465         }
01466 
01467       
01468       template<class _InIterator>
01469         static _CharT*
01470          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
01471               input_iterator_tag);
01472 
01473       
01474       
01475       template<class _FwdIterator>
01476         static _CharT*
01477         _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
01478              forward_iterator_tag);
01479 
01480       static _CharT*
01481       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
01482 
01483     public:
01484 
01496       size_type
01497       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
01498 
01506       void
01507       swap(basic_string& __s);
01508 
01509       
01516       const _CharT*
01517       c_str() const
01518       { return _M_data(); }
01519 
01526       const _CharT*
01527       data() const
01528       { return _M_data(); }
01529 
01533       allocator_type
01534       get_allocator() const
01535       { return _M_dataplus; }
01536 
01548       size_type
01549       find(const _CharT* __s, size_type __pos, size_type __n) const;
01550 
01561       size_type
01562       find(const basic_string& __str, size_type __pos = 0) const
01563       { return this->find(__str.data(), __pos, __str.size()); }
01564 
01575       size_type
01576       find(const _CharT* __s, size_type __pos = 0) const
01577       {
01578     __glibcxx_requires_string(__s);
01579     return this->find(__s, __pos, traits_type::length(__s));
01580       }
01581 
01592       size_type
01593       find(_CharT __c, size_type __pos = 0) const;
01594 
01605       size_type
01606       rfind(const basic_string& __str, size_type __pos = npos) const
01607       { return this->rfind(__str.data(), __pos, __str.size()); }
01608 
01620       size_type
01621       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
01622 
01633       size_type
01634       rfind(const _CharT* __s, size_type __pos = npos) const
01635       {
01636     __glibcxx_requires_string(__s);
01637     return this->rfind(__s, __pos, traits_type::length(__s));
01638       }
01639 
01650       size_type
01651       rfind(_CharT __c, size_type __pos = npos) const;
01652 
01663       size_type
01664       find_first_of(const basic_string& __str, size_type __pos = 0) const
01665       { return this->find_first_of(__str.data(), __pos, __str.size()); }
01666 
01678       size_type
01679       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
01680 
01691       size_type
01692       find_first_of(const _CharT* __s, size_type __pos = 0) const
01693       {
01694     __glibcxx_requires_string(__s);
01695     return this->find_first_of(__s, __pos, traits_type::length(__s));
01696       }
01697 
01710       size_type
01711       find_first_of(_CharT __c, size_type __pos = 0) const
01712       { return this->find(__c, __pos); }
01713 
01724       size_type
01725       find_last_of(const basic_string& __str, size_type __pos = npos) const
01726       { return this->find_last_of(__str.data(), __pos, __str.size()); }
01727 
01739       size_type
01740       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
01741 
01752       size_type
01753       find_last_of(const _CharT* __s, size_type __pos = npos) const
01754       {
01755     __glibcxx_requires_string(__s);
01756     return this->find_last_of(__s, __pos, traits_type::length(__s));
01757       }
01758 
01771       size_type
01772       find_last_of(_CharT __c, size_type __pos = npos) const
01773       { return this->rfind(__c, __pos); }
01774 
01785       size_type
01786       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
01787       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
01788 
01800       size_type
01801       find_first_not_of(const _CharT* __s, size_type __pos,
01802             size_type __n) const;
01803 
01814       size_type
01815       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
01816       {
01817     __glibcxx_requires_string(__s);
01818     return this->find_first_not_of(__s, __pos, traits_type::length(__s));
01819       }
01820 
01831       size_type
01832       find_first_not_of(_CharT __c, size_type __pos = 0) const;
01833 
01844       size_type
01845       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
01846       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
01847 
01860       size_type
01861       find_last_not_of(const _CharT* __s, size_type __pos,
01862                size_type __n) const;
01873       size_type
01874       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
01875       {
01876     __glibcxx_requires_string(__s);
01877     return this->find_last_not_of(__s, __pos, traits_type::length(__s));
01878       }
01879 
01890       size_type
01891       find_last_not_of(_CharT __c, size_type __pos = npos) const;
01892 
01905       basic_string
01906       substr(size_type __pos = 0, size_type __n = npos) const
01907       { return basic_string(*this,
01908                 _M_check(__pos, "basic_string::substr"), __n); }
01909 
01923       int
01924       compare(const basic_string& __str) const
01925       {
01926     const size_type __size = this->size();
01927     const size_type __osize = __str.size();
01928     const size_type __len = std::min(__size, __osize);
01929 
01930     int __r = traits_type::compare(_M_data(), __str.data(), __len);
01931     if (!__r)
01932       __r =  __size - __osize;
01933     return __r;
01934       }
01935 
01953       int
01954       compare(size_type __pos, size_type __n, const basic_string& __str) const;
01955 
01977       int
01978       compare(size_type __pos1, size_type __n1, const basic_string& __str,
01979           size_type __pos2, size_type __n2) const;
01980 
01995       int
01996       compare(const _CharT* __s) const;
01997 
01998       
01999       
02018       int
02019       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
02020 
02043       int
02044       compare(size_type __pos, size_type __n1, const _CharT* __s,
02045           size_type __n2) const;
02046   };
02047 
02048   template<typename _CharT, typename _Traits, typename _Alloc>
02049     inline basic_string<_CharT, _Traits, _Alloc>::
02050     basic_string()
02051 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
02052     : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
02053 #else
02054     : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
02055 #endif
02056 
02057   
02064   template<typename _CharT, typename _Traits, typename _Alloc>
02065     basic_string<_CharT, _Traits, _Alloc>
02066     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02067           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02068     {
02069       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
02070       __str.append(__rhs);
02071       return __str;
02072     }
02073 
02080   template<typename _CharT, typename _Traits, typename _Alloc>
02081     basic_string<_CharT,_Traits,_Alloc>
02082     operator+(const _CharT* __lhs,
02083           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
02084 
02091   template<typename _CharT, typename _Traits, typename _Alloc>
02092     basic_string<_CharT,_Traits,_Alloc>
02093     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
02094 
02101   template<typename _CharT, typename _Traits, typename _Alloc>
02102     inline basic_string<_CharT, _Traits, _Alloc>
02103     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02104          const _CharT* __rhs)
02105     {
02106       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
02107       __str.append(__rhs);
02108       return __str;
02109     }
02110 
02117   template<typename _CharT, typename _Traits, typename _Alloc>
02118     inline basic_string<_CharT, _Traits, _Alloc>
02119     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
02120     {
02121       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
02122       typedef typename __string_type::size_type     __size_type;
02123       __string_type __str(__lhs);
02124       __str.append(__size_type(1), __rhs);
02125       return __str;
02126     }
02127 
02128   
02135   template<typename _CharT, typename _Traits, typename _Alloc>
02136     inline bool
02137     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02138            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02139     { return __lhs.compare(__rhs) == 0; }
02140 
02147   template<typename _CharT, typename _Traits, typename _Alloc>
02148     inline bool
02149     operator==(const _CharT* __lhs,
02150            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02151     { return __rhs.compare(__lhs) == 0; }
02152 
02159   template<typename _CharT, typename _Traits, typename _Alloc>
02160     inline bool
02161     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02162            const _CharT* __rhs)
02163     { return __lhs.compare(__rhs) == 0; }
02164 
02165   
02172   template<typename _CharT, typename _Traits, typename _Alloc>
02173     inline bool
02174     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02175            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02176     { return __rhs.compare(__lhs) != 0; }
02177 
02184   template<typename _CharT, typename _Traits, typename _Alloc>
02185     inline bool
02186     operator!=(const _CharT* __lhs,
02187            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02188     { return __rhs.compare(__lhs) != 0; }
02189 
02196   template<typename _CharT, typename _Traits, typename _Alloc>
02197     inline bool
02198     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02199            const _CharT* __rhs)
02200     { return __lhs.compare(__rhs) != 0; }
02201 
02202   
02209   template<typename _CharT, typename _Traits, typename _Alloc>
02210     inline bool
02211     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02212           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02213     { return __lhs.compare(__rhs) < 0; }
02214 
02221   template<typename _CharT, typename _Traits, typename _Alloc>
02222     inline bool
02223     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02224           const _CharT* __rhs)
02225     { return __lhs.compare(__rhs) < 0; }
02226 
02233   template<typename _CharT, typename _Traits, typename _Alloc>
02234     inline bool
02235     operator<(const _CharT* __lhs,
02236           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02237     { return __rhs.compare(__lhs) > 0; }
02238 
02239   
02246   template<typename _CharT, typename _Traits, typename _Alloc>
02247     inline bool
02248     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02249           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02250     { return __lhs.compare(__rhs) > 0; }
02251 
02258   template<typename _CharT, typename _Traits, typename _Alloc>
02259     inline bool
02260     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02261           const _CharT* __rhs)
02262     { return __lhs.compare(__rhs) > 0; }
02263 
02270   template<typename _CharT, typename _Traits, typename _Alloc>
02271     inline bool
02272     operator>(const _CharT* __lhs,
02273           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02274     { return __rhs.compare(__lhs) < 0; }
02275 
02276   
02283   template<typename _CharT, typename _Traits, typename _Alloc>
02284     inline bool
02285     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02286            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02287     { return __lhs.compare(__rhs) <= 0; }
02288 
02295   template<typename _CharT, typename _Traits, typename _Alloc>
02296     inline bool
02297     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02298            const _CharT* __rhs)
02299     { return __lhs.compare(__rhs) <= 0; }
02300 
02307   template<typename _CharT, typename _Traits, typename _Alloc>
02308     inline bool
02309     operator<=(const _CharT* __lhs,
02310            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02311     { return __rhs.compare(__lhs) >= 0; }
02312 
02313   
02320   template<typename _CharT, typename _Traits, typename _Alloc>
02321     inline bool
02322     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02323            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02324     { return __lhs.compare(__rhs) >= 0; }
02325 
02332   template<typename _CharT, typename _Traits, typename _Alloc>
02333     inline bool
02334     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02335            const _CharT* __rhs)
02336     { return __lhs.compare(__rhs) >= 0; }
02337 
02344   template<typename _CharT, typename _Traits, typename _Alloc>
02345     inline bool
02346     operator>=(const _CharT* __lhs,
02347          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02348     { return __rhs.compare(__lhs) <= 0; }
02349 
02357   template<typename _CharT, typename _Traits, typename _Alloc>
02358     inline void
02359     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
02360      basic_string<_CharT, _Traits, _Alloc>& __rhs)
02361     { __lhs.swap(__rhs); }
02362 
02374   template<typename _CharT, typename _Traits, typename _Alloc>
02375     basic_istream<_CharT, _Traits>&
02376     operator>>(basic_istream<_CharT, _Traits>& __is,
02377            basic_string<_CharT, _Traits, _Alloc>& __str);
02378 
02379   template<>
02380     basic_istream<char>&
02381     operator>>(basic_istream<char>& __is, basic_string<char>& __str);
02382 
02392   template<typename _CharT, typename _Traits, typename _Alloc>
02393     basic_ostream<_CharT, _Traits>&
02394     operator<<(basic_ostream<_CharT, _Traits>& __os,
02395            const basic_string<_CharT, _Traits, _Alloc>& __str);
02396 
02410   template<typename _CharT, typename _Traits, typename _Alloc>
02411     basic_istream<_CharT, _Traits>&
02412     getline(basic_istream<_CharT, _Traits>& __is,
02413         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
02414 
02427   template<typename _CharT, typename _Traits, typename _Alloc>
02428     inline basic_istream<_CharT, _Traits>&
02429     getline(basic_istream<_CharT, _Traits>& __is,
02430         basic_string<_CharT, _Traits, _Alloc>& __str);
02431     
02432   template<>
02433     basic_istream<char>&
02434     getline(basic_istream<char>& __in, basic_string<char>& __str,
02435         char __delim);
02436 
02437 #ifdef _GLIBCXX_USE_WCHAR_T
02438   template<>
02439     basic_istream<wchar_t>&
02440     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
02441         wchar_t __delim);
02442 #endif  
02443 } 
02444 
02445 #endif