basic_string.h

Go to the documentation of this file.
00001 // Components for manipulating sequences of characters -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 //
00032 // ISO C++ 14882: 21 Strings library
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 {
00107   // 21.3  Template class basic_string
00108   template<typename _CharT, typename _Traits, typename _Alloc>
00109     class basic_string
00110     {
00111       // Types:
00112     public:
00113       typedef _Traits                       traits_type;
00114       typedef typename _Traits::char_type           value_type;
00115       typedef _Alloc                        allocator_type;
00116       typedef typename _Alloc::size_type            size_type;
00117       typedef typename _Alloc::difference_type          difference_type;
00118       typedef typename _Alloc::reference            reference;
00119       typedef typename _Alloc::const_reference          const_reference;
00120       typedef typename _Alloc::pointer              pointer;
00121       typedef typename _Alloc::const_pointer            const_pointer;
00122       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
00123       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
00124                                                             const_iterator;
00125       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
00126       typedef std::reverse_iterator<iterator>           reverse_iterator;
00127 
00128     private:
00129       // _Rep: string representation
00130       //   Invariants:
00131       //   1. String really contains _M_length + 1 characters; last is set
00132       //      to 0 only on call to c_str().  We avoid instantiating
00133       //      _CharT() where the interface does not require it.
00134       //   2. _M_capacity >= _M_length
00135       //      Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
00136       //   3. _M_references has three states:
00137       //      -1: leaked, one reference, no ref-copies allowed, non-const.
00138       //       0: one reference, non-const.
00139       //     n>0: n + 1 references, operations require a lock, const.
00140       //   4. All fields==0 is an empty string, given the extra storage
00141       //      beyond-the-end for a null terminator; thus, the shared
00142       //      empty string representation needs no constructor.
00143       struct _Rep
00144       {
00145     // Types:
00146     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
00147 
00148     // (Public) Data members:
00149 
00150     // The maximum number of individual char_type elements of an
00151     // individual string is determined by _S_max_size. This is the
00152     // value that will be returned by max_size().  (Whereas npos
00153     // is the maximum number of bytes the allocator can allocate.)
00154     // If one was to divvy up the theoretical largest size string,
00155     // with a terminating character and m _CharT elements, it'd
00156     // look like this:
00157     // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
00158     // Solving for m:
00159     // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
00160     // In addition, this implementation quarters this ammount.
00161     static const size_type  _S_max_size;
00162     static const _CharT     _S_terminal;
00163 
00164     size_type       _M_length;
00165     size_type       _M_capacity;
00166     _Atomic_word        _M_references;
00167 
00168         bool
00169     _M_is_leaked() const
00170         { return _M_references < 0; }
00171 
00172         bool
00173     _M_is_shared() const
00174         { return _M_references > 0; }
00175 
00176         void
00177     _M_set_leaked()
00178         { _M_references = -1; }
00179 
00180         void
00181     _M_set_sharable()
00182         { _M_references = 0; }
00183 
00184     _CharT*
00185     _M_refdata() throw()
00186     { return reinterpret_cast<_CharT*>(this + 1); }
00187 
00188     _CharT&
00189     operator[](size_t __s) throw()
00190     { return _M_refdata() [__s]; }
00191 
00192     _CharT*
00193     _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
00194     {
00195       return (!_M_is_leaked() && __alloc1 == __alloc2)
00196               ? _M_refcopy() : _M_clone(__alloc1);
00197     }
00198 
00199     // Create & Destroy
00200     static _Rep*
00201     _S_create(size_t, const _Alloc&);
00202 
00203     void
00204     _M_dispose(const _Alloc& __a)
00205     {
00206       if (__exchange_and_add(&_M_references, -1) <= 0)
00207         _M_destroy(__a);
00208     }  // XXX MT
00209 
00210     void
00211     _M_destroy(const _Alloc&) throw();
00212 
00213     _CharT*
00214     _M_refcopy() throw()
00215     {
00216       __atomic_add(&_M_references, 1);
00217       return _M_refdata();
00218     }  // XXX MT
00219 
00220     _CharT*
00221     _M_clone(const _Alloc&, size_type __res = 0);
00222       };
00223 
00224       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
00225       struct _Alloc_hider : _Alloc
00226       {
00227     _Alloc_hider(_CharT* __dat, const _Alloc& __a)
00228     : _Alloc(__a), _M_p(__dat) { }
00229 
00230     _CharT* _M_p; // The actual data.
00231       };
00232 
00233     public:
00234       // Data Members (public):
00235       // NB: This is an unsigned type, and thus represents the maximum
00236       // size that the allocator can hold.
00237       static const size_type    npos = static_cast<size_type>(-1);
00238 
00239     private:
00240       // Data Members (private):
00241       mutable _Alloc_hider  _M_dataplus;
00242 
00243       // The following storage is init'd to 0 by the linker, resulting
00244       // (carefully) in an empty string with one reference.
00245       static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
00246 
00247       _CharT*
00248       _M_data() const
00249       { return  _M_dataplus._M_p; }
00250 
00251       _CharT*
00252       _M_data(_CharT* __p)
00253       { return (_M_dataplus._M_p = __p); }
00254 
00255       _Rep*
00256       _M_rep() const
00257       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
00258 
00259       // For the internal use we have functions similar to `begin'/`end'
00260       // but they do not call _M_leak.
00261       iterator
00262       _M_ibegin() const { return iterator(_M_data()); }
00263 
00264       iterator
00265       _M_iend() const { return iterator(_M_data() + this->size()); }
00266 
00267       void
00268       _M_leak()    // for use in begin() & non-const op[]
00269       {
00270     if (!_M_rep()->_M_is_leaked())
00271       _M_leak_hard();
00272       }
00273 
00274       iterator
00275       _M_check(size_type __pos) const
00276       {
00277     if (__pos > this->size())
00278       __throw_out_of_range("basic_string::_M_check");
00279     return _M_ibegin() + __pos;
00280       }
00281 
00282       // NB: _M_fold doesn't check for a bad __pos1 value.
00283       iterator
00284       _M_fold(size_type __pos, size_type __off) const
00285       {
00286     bool __testoff =  __off < this->size() - __pos;
00287     size_type __newoff = __testoff ? __off : this->size() - __pos;
00288     return (_M_ibegin() + __pos + __newoff);
00289       }
00290 
00291       // _S_copy_chars is a separate template to permit specialization
00292       // to optimize for the common case of pointers as iterators.
00293       template<class _Iterator>
00294         static void
00295         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00296         {
00297       for (; __k1 != __k2; ++__k1, ++__p)
00298         traits_type::assign(*__p, *__k1); // These types are off.
00299     }
00300 
00301       static void
00302       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
00303       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00304 
00305       static void
00306       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
00307       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00308 
00309       static void
00310       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00311       { traits_type::copy(__p, __k1, __k2 - __k1); }
00312 
00313       static void
00314       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00315       { traits_type::copy(__p, __k1, __k2 - __k1); }
00316 
00317       void
00318       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
00319 
00320       void
00321       _M_leak_hard();
00322 
00323       static _Rep&
00324       _S_empty_rep()
00325       { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
00326 
00327     public:
00328       // Construct/copy/destroy:
00329       // NB: We overload ctors in some cases instead of using default
00330       // arguments, per 17.4.4.4 para. 2 item 2.
00331 
00332       inline
00333       basic_string();
00334 
00335       explicit
00336       basic_string(const _Alloc& __a);
00337 
00338       // NB: per LWG issue 42, semantics different from IS:
00339       basic_string(const basic_string& __str);
00340       basic_string(const basic_string& __str, size_type __pos,
00341            size_type __n = npos);
00342       basic_string(const basic_string& __str, size_type __pos,
00343            size_type __n, const _Alloc& __a);
00344 
00345       basic_string(const _CharT* __s, size_type __n,
00346            const _Alloc& __a = _Alloc());
00347       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
00348       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
00349 
00350       template<class _InputIterator>
00351         basic_string(_InputIterator __beg, _InputIterator __end,
00352              const _Alloc& __a = _Alloc());
00353 
00354       ~basic_string()
00355       { _M_rep()->_M_dispose(this->get_allocator()); }
00356 
00357       basic_string&
00358       operator=(const basic_string& __str) { return this->assign(__str); }
00359 
00360       basic_string&
00361       operator=(const _CharT* __s) { return this->assign(__s); }
00362 
00363       basic_string&
00364       operator=(_CharT __c) { return this->assign(1, __c); }
00365 
00366       // Iterators:
00367       iterator
00368       begin()
00369       {
00370     _M_leak();
00371     return iterator(_M_data());
00372       }
00373 
00374       const_iterator
00375       begin() const
00376       { return const_iterator(_M_data()); }
00377 
00378       iterator
00379       end()
00380       {
00381          _M_leak();
00382      return iterator(_M_data() + this->size());
00383       }
00384 
00385       const_iterator
00386       end() const
00387       { return const_iterator(_M_data() + this->size()); }
00388 
00389       reverse_iterator
00390       rbegin()
00391       { return reverse_iterator(this->end()); }
00392 
00393       const_reverse_iterator
00394       rbegin() const
00395       { return const_reverse_iterator(this->end()); }
00396 
00397       reverse_iterator
00398       rend()
00399       { return reverse_iterator(this->begin()); }
00400 
00401       const_reverse_iterator
00402       rend() const
00403       { return const_reverse_iterator(this->begin()); }
00404 
00405     public:
00406       // Capacity:
00407       size_type
00408       size() const { return _M_rep()->_M_length; }
00409 
00410       size_type
00411       length() const { return _M_rep()->_M_length; }
00412 
00413       size_type
00414       max_size() const { return _Rep::_S_max_size; }
00415 
00416       void
00417       resize(size_type __n, _CharT __c);
00418 
00419       void
00420       resize(size_type __n) { this->resize(__n, _CharT()); }
00421 
00422       size_type
00423       capacity() const { return _M_rep()->_M_capacity; }
00424 
00425       void
00426       reserve(size_type __res_arg = 0);
00427 
00428       void
00429       clear() { _M_mutate(0, this->size(), 0); }
00430 
00431       bool
00432       empty() const { return this->size() == 0; }
00433 
00434       // Element access:
00435       const_reference
00436       operator[] (size_type __pos) const
00437       { return _M_data()[__pos]; }
00438 
00439       reference
00440       operator[](size_type __pos)
00441       {
00442     _M_leak();
00443     return _M_data()[__pos];
00444       }
00445 
00446       const_reference
00447       at(size_type __n) const
00448       {
00449     if (__n >= this->size())
00450       __throw_out_of_range("basic_string::at");
00451     return _M_data()[__n];
00452       }
00453 
00454       reference
00455       at(size_type __n)
00456       {
00457     if (__n >= size())
00458       __throw_out_of_range("basic_string::at");
00459     _M_leak();
00460     return _M_data()[__n];
00461       }
00462 
00463       // Modifiers:
00464       basic_string&
00465       operator+=(const basic_string& __str) { return this->append(__str); }
00466 
00467       basic_string&
00468       operator+=(const _CharT* __s) { return this->append(__s); }
00469 
00470       basic_string&
00471       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
00472 
00473       basic_string&
00474       append(const basic_string& __str);
00475 
00476       basic_string&
00477       append(const basic_string& __str, size_type __pos, size_type __n);
00478 
00479       basic_string&
00480       append(const _CharT* __s, size_type __n);
00481 
00482       basic_string&
00483       append(const _CharT* __s)
00484       { return this->append(__s, traits_type::length(__s)); }
00485 
00486       basic_string&
00487       append(size_type __n, _CharT __c);
00488 
00489       template<class _InputIterator>
00490         basic_string&
00491         append(_InputIterator __first, _InputIterator __last)
00492         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
00493 
00494       void
00495       push_back(_CharT __c)
00496       { this->replace(_M_iend(), _M_iend(), 1, __c); }
00497 
00498       basic_string&
00499       assign(const basic_string& __str);
00500 
00501       basic_string&
00502       assign(const basic_string& __str, size_type __pos, size_type __n)
00503       {
00504     const size_type __strsize = __str.size();
00505     if (__pos > __strsize)
00506       __throw_out_of_range("basic_string::assign");
00507     const bool __testn = __n < __strsize - __pos;
00508     const size_type __newsize = __testn ? __n : __strsize - __pos;
00509     return this->assign(__str._M_data() + __pos, __newsize);
00510       }
00511 
00512       basic_string&
00513       assign(const _CharT* __s, size_type __n)
00514       {
00515     if (__n > this->max_size())
00516       __throw_length_error("basic_string::assign");
00517     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00518         || less<const _CharT*>()(_M_data() + this->size(), __s))
00519       return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
00520     else
00521       {
00522         // Work in-place
00523         const size_type __pos = __s - _M_data();
00524         if (__pos >= __n)
00525           traits_type::copy(_M_data(), __s, __n);
00526         else if (__pos)
00527           traits_type::move(_M_data(), __s, __n);
00528         _M_rep()->_M_length = __n;
00529         _M_data()[__n] = _Rep::_S_terminal;
00530         return *this;
00531       }
00532       }
00533 
00534       basic_string&
00535       assign(const _CharT* __s)
00536       { return this->assign(__s, traits_type::length(__s)); }
00537 
00538       basic_string&
00539       assign(size_type __n, _CharT __c)
00540       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
00541 
00542       template<class _InputIterator>
00543         basic_string&
00544         assign(_InputIterator __first, _InputIterator __last)
00545         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
00546 
00547       void
00548       insert(iterator __p, size_type __n, _CharT __c)
00549       { this->replace(__p, __p, __n, __c);  }
00550 
00551       template<class _InputIterator>
00552         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
00553         { this->replace(__p, __p, __beg, __end); }
00554 
00555       basic_string&
00556       insert(size_type __pos1, const basic_string& __str)
00557       { return this->insert(__pos1, __str, 0, __str.size()); }
00558 
00559       basic_string&
00560       insert(size_type __pos1, const basic_string& __str,
00561          size_type __pos2, size_type __n)
00562       {
00563     const size_type __strsize = __str.size();
00564     if (__pos2 > __strsize)
00565       __throw_out_of_range("basic_string::insert");
00566     const bool __testn = __n < __strsize - __pos2;
00567     const size_type __newsize = __testn ? __n : __strsize - __pos2;
00568     return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
00569       }
00570 
00571       basic_string&
00572       insert(size_type __pos, const _CharT* __s, size_type __n)
00573       {
00574     const size_type __size = this->size();
00575     if (__pos > __size)
00576       __throw_out_of_range("basic_string::insert");
00577     if (__size > this->max_size() - __n)
00578       __throw_length_error("basic_string::insert");
00579     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00580         || less<const _CharT*>()(_M_data() + __size, __s))
00581       return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos,
00582                  __s, __s + __n);
00583     else
00584       {
00585         // Work in-place. If _M_mutate reallocates the string, __s
00586         // does not point anymore to valid data, therefore we save its
00587         // offset, then we restore it.
00588         const size_type __off = __s - _M_data();
00589         _M_mutate(__pos, 0, __n);
00590         __s = _M_data() + __off;
00591         _CharT* __p = _M_data() + __pos;
00592         if (__s  + __n <= __p)
00593           traits_type::copy(__p, __s, __n);
00594         else if (__s >= __p)
00595           traits_type::copy(__p, __s + __n, __n);
00596         else
00597           {
00598         traits_type::copy(__p, __s, __p - __s);
00599         traits_type::copy(__p + (__p - __s), __p + __n, __n - (__p - __s));
00600           }
00601         return *this;
00602       }
00603        }
00604 
00605       basic_string&
00606       insert(size_type __pos, const _CharT* __s)
00607       { return this->insert(__pos, __s, traits_type::length(__s)); }
00608 
00609       basic_string&
00610       insert(size_type __pos, size_type __n, _CharT __c)
00611       {
00612     this->insert(_M_check(__pos), __n, __c);
00613     return *this;
00614       }
00615 
00616       iterator
00617       insert(iterator __p, _CharT __c = _CharT())
00618       {
00619     size_type __pos = __p - _M_ibegin();
00620     this->insert(_M_check(__pos), size_type(1), __c);
00621     _M_rep()->_M_set_leaked();
00622     return this->_M_ibegin() + __pos;
00623       }
00624 
00625       basic_string&
00626       erase(size_type __pos = 0, size_type __n = npos)
00627       {
00628     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
00629                  _M_data(), _M_data());
00630       }
00631 
00632       iterator
00633       erase(iterator __position)
00634       {
00635     size_type __i = __position - _M_ibegin();
00636         this->replace(__position, __position + 1, _M_data(), _M_data());
00637     _M_rep()->_M_set_leaked();
00638     return _M_ibegin() + __i;
00639       }
00640 
00641       iterator
00642       erase(iterator __first, iterator __last)
00643       {
00644         size_type __i = __first - _M_ibegin();
00645     this->replace(__first, __last, _M_data(), _M_data());
00646     _M_rep()->_M_set_leaked();
00647        return _M_ibegin() + __i;
00648       }
00649 
00650       basic_string&
00651       replace(size_type __pos, size_type __n, const basic_string& __str)
00652       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
00653 
00654       basic_string&
00655       replace(size_type __pos1, size_type __n1, const basic_string& __str,
00656           size_type __pos2, size_type __n2);
00657 
00658       basic_string&
00659       replace(size_type __pos, size_type __n1, const _CharT* __s,
00660           size_type __n2)
00661       {
00662     const size_type __size = this->size();
00663     if (__pos > __size)
00664       __throw_out_of_range("basic_string::replace");
00665     const bool __testn1 = __n1 < __size - __pos;
00666     const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
00667     if (__size - __foldn1 > this->max_size() - __n2)
00668       __throw_length_error("basic_string::replace");
00669     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00670         || less<const _CharT*>()(_M_data() + __size, __s))
00671       return _M_replace_safe(_M_ibegin() + __pos,
00672                  _M_ibegin() + __pos + __foldn1, __s, __s + __n2);
00673     // Todo: optimized in-place replace.
00674     else return
00675            _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1,
00676               __s, __s + __n2,
00677               typename iterator_traits<const _CharT*>::iterator_category());
00678       }
00679 
00680       basic_string&
00681       replace(size_type __pos, size_type __n1, const _CharT* __s)
00682       { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
00683 
00684       basic_string&
00685       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00686       { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
00687 
00688       basic_string&
00689       replace(iterator __i1, iterator __i2, const basic_string& __str)
00690       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
00691 
00692       basic_string&
00693       replace(iterator __i1, iterator __i2,
00694                            const _CharT* __s, size_type __n)
00695       { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
00696 
00697       basic_string&
00698       replace(iterator __i1, iterator __i2, const _CharT* __s)
00699       { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
00700 
00701       basic_string&
00702       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
00703 
00704       template<class _InputIterator>
00705         basic_string&
00706         replace(iterator __i1, iterator __i2,
00707         _InputIterator __k1, _InputIterator __k2)
00708         { return _M_replace(__i1, __i2, __k1, __k2,
00709          typename iterator_traits<_InputIterator>::iterator_category()); }
00710 
00711       // Specializations for the common case of pointer and iterator:
00712       // useful to avoid the overhead of temporary buffering in _M_replace.
00713       basic_string&
00714       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
00715         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
00716                    __k1, __k2 - __k1); }
00717 
00718       basic_string&
00719       replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
00720         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
00721                    __k1, __k2 - __k1); }
00722 
00723       basic_string&
00724       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
00725         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
00726                    __k1.base(), __k2 - __k1);
00727     }
00728 
00729       basic_string&
00730       replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
00731         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
00732                    __k1.base(), __k2 - __k1);
00733     }
00734 
00735     private:
00736       template<class _InputIterator>
00737         basic_string&
00738         _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
00739            _InputIterator __k2, input_iterator_tag);
00740 
00741       template<class _ForwardIterator>
00742         basic_string&
00743         _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
00744            _ForwardIterator __k2);
00745 
00746       // _S_construct_aux is used to implement the 21.3.1 para 15 which
00747       // requires special behaviour if _InIter is an integral type
00748       template<class _InIter>
00749         static _CharT*
00750         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
00751              __false_type)
00752     {
00753           typedef typename iterator_traits<_InIter>::iterator_category _Tag;
00754           return _S_construct(__beg, __end, __a, _Tag());
00755     }
00756 
00757       template<class _InIter>
00758         static _CharT*
00759         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
00760              __true_type)
00761     {
00762       return _S_construct(static_cast<size_type>(__beg),
00763                   static_cast<value_type>(__end), __a);
00764     }
00765 
00766       template<class _InIter>
00767         static _CharT*
00768         _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
00769     {
00770       typedef typename _Is_integer<_InIter>::_Integral _Integral;
00771       return _S_construct_aux(__beg, __end, __a, _Integral());
00772         }
00773 
00774       // For Input Iterators, used in istreambuf_iterators, etc.
00775       template<class _InIter>
00776         static _CharT*
00777          _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
00778               input_iterator_tag);
00779 
00780       // For forward_iterators up to random_access_iterators, used for
00781       // string::iterator, _CharT*, etc.
00782       template<class _FwdIter>
00783         static _CharT*
00784         _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
00785              forward_iterator_tag);
00786 
00787       static _CharT*
00788       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
00789 
00790     public:
00791 
00792       size_type
00793       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
00794 
00795       void
00796       swap(basic_string<_CharT, _Traits, _Alloc>& __s);
00797 
00798       // String operations:
00799       const _CharT*
00800       c_str() const
00801       {
00802     // MT: This assumes concurrent writes are OK.
00803     size_type __n = this->size();
00804     traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
00805         return _M_data();
00806       }
00807 
00808       const _CharT*
00809       data() const { return _M_data(); }
00810 
00811       allocator_type
00812       get_allocator() const { return _M_dataplus; }
00813 
00814       size_type
00815       find(const _CharT* __s, size_type __pos, size_type __n) const;
00816 
00817       size_type
00818       find(const basic_string& __str, size_type __pos = 0) const
00819       { return this->find(__str.data(), __pos, __str.size()); }
00820 
00821       size_type
00822       find(const _CharT* __s, size_type __pos = 0) const
00823       { return this->find(__s, __pos, traits_type::length(__s)); }
00824 
00825       size_type
00826       find(_CharT __c, size_type __pos = 0) const;
00827 
00828       size_type
00829       rfind(const basic_string& __str, size_type __pos = npos) const
00830       { return this->rfind(__str.data(), __pos, __str.size()); }
00831 
00832       size_type
00833       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
00834 
00835       size_type
00836       rfind(const _CharT* __s, size_type __pos = npos) const
00837       { return this->rfind(__s, __pos, traits_type::length(__s)); }
00838 
00839       size_type
00840       rfind(_CharT __c, size_type __pos = npos) const;
00841 
00842       size_type
00843       find_first_of(const basic_string& __str, size_type __pos = 0) const
00844       { return this->find_first_of(__str.data(), __pos, __str.size()); }
00845 
00846       size_type
00847       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
00848 
00849       size_type
00850       find_first_of(const _CharT* __s, size_type __pos = 0) const
00851       { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
00852 
00853       size_type
00854       find_first_of(_CharT __c, size_type __pos = 0) const
00855       { return this->find(__c, __pos); }
00856 
00857       size_type
00858       find_last_of(const basic_string& __str, size_type __pos = npos) const
00859       { return this->find_last_of(__str.data(), __pos, __str.size()); }
00860 
00861       size_type
00862       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
00863 
00864       size_type
00865       find_last_of(const _CharT* __s, size_type __pos = npos) const
00866       { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
00867 
00868       size_type
00869       find_last_of(_CharT __c, size_type __pos = npos) const
00870       { return this->rfind(__c, __pos); }
00871 
00872       size_type
00873       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00874       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
00875 
00876       size_type
00877       find_first_not_of(const _CharT* __s, size_type __pos,
00878             size_type __n) const;
00879 
00880       size_type
00881       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00882       { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
00883 
00884       size_type
00885       find_first_not_of(_CharT __c, size_type __pos = 0) const;
00886 
00887       size_type
00888       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
00889       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
00890 
00891       size_type
00892       find_last_not_of(const _CharT* __s, size_type __pos,
00893                size_type __n) const;
00894       size_type
00895       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
00896       { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
00897 
00898       size_type
00899       find_last_not_of(_CharT __c, size_type __pos = npos) const;
00900 
00901       basic_string
00902       substr(size_type __pos = 0, size_type __n = npos) const
00903       {
00904     if (__pos > this->size())
00905       __throw_out_of_range("basic_string::substr");
00906     return basic_string(*this, __pos, __n);
00907       }
00908 
00909       int
00910       compare(const basic_string& __str) const
00911       {
00912     size_type __size = this->size();
00913     size_type __osize = __str.size();
00914     size_type __len = min(__size, __osize);
00915 
00916     int __r = traits_type::compare(_M_data(), __str.data(), __len);
00917     if (!__r)
00918       __r =  __size - __osize;
00919     return __r;
00920       }
00921 
00922       int
00923       compare(size_type __pos, size_type __n, const basic_string& __str) const;
00924 
00925       int
00926       compare(size_type __pos1, size_type __n1, const basic_string& __str,
00927           size_type __pos2, size_type __n2) const;
00928 
00929       int
00930       compare(const _CharT* __s) const;
00931 
00932       // _GLIBCPP_RESOLVE_LIB_DEFECTS
00933       // 5. String::compare specification questionable
00934       int
00935       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
00936 
00937       int
00938       compare(size_type __pos, size_type __n1, const _CharT* __s,
00939           size_type __n2) const;
00940   };
00941 
00942 
00943   template<typename _CharT, typename _Traits, typename _Alloc>
00944     inline basic_string<_CharT, _Traits, _Alloc>::
00945     basic_string()
00946     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
00947 
00948   // operator+
00949   template<typename _CharT, typename _Traits, typename _Alloc>
00950     basic_string<_CharT, _Traits, _Alloc>
00951     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00952           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00953     {
00954       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00955       __str.append(__rhs);
00956       return __str;
00957     }
00958 
00959   template<typename _CharT, typename _Traits, typename _Alloc>
00960     basic_string<_CharT,_Traits,_Alloc>
00961     operator+(const _CharT* __lhs,
00962           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00963 
00964   template<typename _CharT, typename _Traits, typename _Alloc>
00965     basic_string<_CharT,_Traits,_Alloc>
00966     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00967 
00968   template<typename _CharT, typename _Traits, typename _Alloc>
00969     inline basic_string<_CharT, _Traits, _Alloc>
00970     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00971          const _CharT* __rhs)
00972     {
00973       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00974       __str.append(__rhs);
00975       return __str;
00976     }
00977 
00978   template<typename _CharT, typename _Traits, typename _Alloc>
00979     inline basic_string<_CharT, _Traits, _Alloc>
00980     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
00981     {
00982       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
00983       typedef typename __string_type::size_type     __size_type;
00984       __string_type __str(__lhs);
00985       __str.append(__size_type(1), __rhs);
00986       return __str;
00987     }
00988 
00989   // operator ==
00990   template<typename _CharT, typename _Traits, typename _Alloc>
00991     inline bool
00992     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00993            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00994     { return __lhs.compare(__rhs) == 0; }
00995 
00996   template<typename _CharT, typename _Traits, typename _Alloc>
00997     inline bool
00998     operator==(const _CharT* __lhs,
00999            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01000     { return __rhs.compare(__lhs) == 0; }
01001 
01002   template<typename _CharT, typename _Traits, typename _Alloc>
01003     inline bool
01004     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01005            const _CharT* __rhs)
01006     { return __lhs.compare(__rhs) == 0; }
01007 
01008   // operator !=
01009   template<typename _CharT, typename _Traits, typename _Alloc>
01010     inline bool
01011     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01012            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01013     { return __rhs.compare(__lhs) != 0; }
01014 
01015   template<typename _CharT, typename _Traits, typename _Alloc>
01016     inline bool
01017     operator!=(const _CharT* __lhs,
01018            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01019     { return __rhs.compare(__lhs) != 0; }
01020 
01021   template<typename _CharT, typename _Traits, typename _Alloc>
01022     inline bool
01023     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01024            const _CharT* __rhs)
01025     { return __lhs.compare(__rhs) != 0; }
01026 
01027   // operator <
01028   template<typename _CharT, typename _Traits, typename _Alloc>
01029     inline bool
01030     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01031           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01032     { return __lhs.compare(__rhs) < 0; }
01033 
01034   template<typename _CharT, typename _Traits, typename _Alloc>
01035     inline bool
01036     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01037           const _CharT* __rhs)
01038     { return __lhs.compare(__rhs) < 0; }
01039 
01040   template<typename _CharT, typename _Traits, typename _Alloc>
01041     inline bool
01042     operator<(const _CharT* __lhs,
01043           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01044     { return __rhs.compare(__lhs) > 0; }
01045 
01046   // operator >
01047   template<typename _CharT, typename _Traits, typename _Alloc>
01048     inline bool
01049     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01050           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01051     { return __lhs.compare(__rhs) > 0; }
01052 
01053   template<typename _CharT, typename _Traits, typename _Alloc>
01054     inline bool
01055     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01056           const _CharT* __rhs)
01057     { return __lhs.compare(__rhs) > 0; }
01058 
01059   template<typename _CharT, typename _Traits, typename _Alloc>
01060     inline bool
01061     operator>(const _CharT* __lhs,
01062           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01063     { return __rhs.compare(__lhs) < 0; }
01064 
01065   // operator <=
01066   template<typename _CharT, typename _Traits, typename _Alloc>
01067     inline bool
01068     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01069            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01070     { return __lhs.compare(__rhs) <= 0; }
01071 
01072   template<typename _CharT, typename _Traits, typename _Alloc>
01073     inline bool
01074     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01075            const _CharT* __rhs)
01076     { return __lhs.compare(__rhs) <= 0; }
01077 
01078   template<typename _CharT, typename _Traits, typename _Alloc>
01079     inline bool
01080     operator<=(const _CharT* __lhs,
01081            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01082   { return __rhs.compare(__lhs) >= 0; }
01083 
01084   // operator >=
01085   template<typename _CharT, typename _Traits, typename _Alloc>
01086     inline bool
01087     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01088            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01089     { return __lhs.compare(__rhs) >= 0; }
01090 
01091   template<typename _CharT, typename _Traits, typename _Alloc>
01092     inline bool
01093     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01094            const _CharT* __rhs)
01095     { return __lhs.compare(__rhs) >= 0; }
01096 
01097   template<typename _CharT, typename _Traits, typename _Alloc>
01098     inline bool
01099     operator>=(const _CharT* __lhs,
01100          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01101     { return __rhs.compare(__lhs) <= 0; }
01102 
01103 
01104   template<typename _CharT, typename _Traits, typename _Alloc>
01105     inline void
01106     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
01107      basic_string<_CharT, _Traits, _Alloc>& __rhs)
01108     { __lhs.swap(__rhs); }
01109 
01110   template<typename _CharT, typename _Traits, typename _Alloc>
01111     basic_istream<_CharT, _Traits>&
01112     operator>>(basic_istream<_CharT, _Traits>& __is,
01113            basic_string<_CharT, _Traits, _Alloc>& __str);
01114 
01115   template<typename _CharT, typename _Traits, typename _Alloc>
01116     basic_ostream<_CharT, _Traits>&
01117     operator<<(basic_ostream<_CharT, _Traits>& __os,
01118            const basic_string<_CharT, _Traits, _Alloc>& __str);
01119 
01120   template<typename _CharT, typename _Traits, typename _Alloc>
01121     basic_istream<_CharT,_Traits>&
01122     getline(basic_istream<_CharT, _Traits>& __is,
01123         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
01124 
01125   template<typename _CharT, typename _Traits, typename _Alloc>
01126     inline basic_istream<_CharT,_Traits>&
01127     getline(basic_istream<_CharT, _Traits>& __is,
01128         basic_string<_CharT, _Traits, _Alloc>& __str);
01129 } // namespace std
01130 
01131 #endif /* _CPP_BITS_STRING_H */

Generated on Thu Nov 21 03:12:46 2002 for libstdc++-v3 Source by doxygen1.2.18-20021030