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, 2003, 2004
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 _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   // 21.3  Template class basic_string
00109   template<typename _CharT, typename _Traits, typename _Alloc>
00110     class basic_string
00111     {
00112       // Types:
00113     public:
00114       typedef _Traits                       traits_type;
00115       typedef typename _Traits::char_type           value_type;
00116       typedef _Alloc                        allocator_type;
00117       typedef typename _Alloc::size_type            size_type;
00118       typedef typename _Alloc::difference_type          difference_type;
00119       typedef typename _Alloc::reference            reference;
00120       typedef typename _Alloc::const_reference          const_reference;
00121       typedef typename _Alloc::pointer              pointer;
00122       typedef typename _Alloc::const_pointer            const_pointer;
00123       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
00124       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
00125                                                             const_iterator;
00126       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00127       typedef std::reverse_iterator<iterator>           reverse_iterator;
00128 
00129     private:
00130       // _Rep: string representation
00131       //   Invariants:
00132       //   1. String really contains _M_length + 1 characters: due to 21.3.4
00133       //      must be kept null-terminated.
00134       //   2. _M_capacity >= _M_length
00135       //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
00136       //   3. _M_refcount 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 
00144       struct _Rep_base
00145       {
00146     size_type       _M_length;
00147     size_type       _M_capacity;
00148     _Atomic_word        _M_refcount;
00149       };
00150 
00151       struct _Rep : _Rep_base
00152       {
00153     // Types:
00154     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
00155 
00156     // (Public) Data members:
00157 
00158     // The maximum number of individual char_type elements of an
00159     // individual string is determined by _S_max_size. This is the
00160     // value that will be returned by max_size().  (Whereas npos
00161     // is the maximum number of bytes the allocator can allocate.)
00162     // If one was to divvy up the theoretical largest size string,
00163     // with a terminating character and m _CharT elements, it'd
00164     // look like this:
00165     // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
00166     // Solving for m:
00167     // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
00168     // In addition, this implementation quarters this amount.
00169     static const size_type  _S_max_size;
00170     static const _CharT _S_terminal;
00171 
00172     // The following storage is init'd to 0 by the linker, resulting
00173         // (carefully) in an empty string with one reference.
00174         static size_type _S_empty_rep_storage[];
00175 
00176         static _Rep&
00177         _S_empty_rep()
00178         { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
00179 
00180         bool
00181     _M_is_leaked() const
00182         { return this->_M_refcount < 0; }
00183 
00184         bool
00185     _M_is_shared() const
00186         { return this->_M_refcount > 0; }
00187 
00188         void
00189     _M_set_leaked()
00190         { this->_M_refcount = -1; }
00191 
00192         void
00193     _M_set_sharable()
00194         { this->_M_refcount = 0; }
00195 
00196     _CharT*
00197     _M_refdata() throw()
00198     { return reinterpret_cast<_CharT*>(this + 1); }
00199 
00200     _CharT*
00201     _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
00202     {
00203       return (!_M_is_leaked() && __alloc1 == __alloc2)
00204               ? _M_refcopy() : _M_clone(__alloc1);
00205     }
00206 
00207     // Create & Destroy
00208     static _Rep*
00209     _S_create(size_type, size_type, const _Alloc&);
00210 
00211     void
00212     _M_dispose(const _Alloc& __a)
00213     {
00214 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
00215       if (__builtin_expect(this != &_S_empty_rep(), false))
00216 #endif
00217         if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0)
00218           _M_destroy(__a);
00219     }  // XXX MT
00220 
00221     void
00222     _M_destroy(const _Alloc&) throw();
00223 
00224     _CharT*
00225     _M_refcopy() throw()
00226     {
00227 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
00228       if (__builtin_expect(this != &_S_empty_rep(), false))
00229 #endif
00230             __gnu_cxx::__atomic_add(&this->_M_refcount, 1);
00231       return _M_refdata();
00232     }  // XXX MT
00233 
00234     _CharT*
00235     _M_clone(const _Alloc&, size_type __res = 0);
00236       };
00237 
00238       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
00239       struct _Alloc_hider : _Alloc
00240       {
00241     _Alloc_hider(_CharT* __dat, const _Alloc& __a)
00242     : _Alloc(__a), _M_p(__dat) { }
00243 
00244     _CharT* _M_p; // The actual data.
00245       };
00246 
00247     public:
00248       // Data Members (public):
00249       // NB: This is an unsigned type, and thus represents the maximum
00250       // size that the allocator can hold.
00253       static const size_type    npos = static_cast<size_type>(-1);
00254 
00255     private:
00256       // Data Members (private):
00257       mutable _Alloc_hider  _M_dataplus;
00258 
00259       _CharT*
00260       _M_data() const
00261       { return  _M_dataplus._M_p; }
00262 
00263       _CharT*
00264       _M_data(_CharT* __p)
00265       { return (_M_dataplus._M_p = __p); }
00266 
00267       _Rep*
00268       _M_rep() const
00269       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
00270 
00271       // For the internal use we have functions similar to `begin'/`end'
00272       // but they do not call _M_leak.
00273       iterator
00274       _M_ibegin() const { return iterator(_M_data()); }
00275 
00276       iterator
00277       _M_iend() const { return iterator(_M_data() + this->size()); }
00278 
00279       void
00280       _M_leak()    // for use in begin() & non-const op[]
00281       {
00282     if (!_M_rep()->_M_is_leaked())
00283       _M_leak_hard();
00284       }
00285 
00286       size_type
00287       _M_check(size_type __pos, const char* __s) const
00288       {
00289     if (__pos > this->size())
00290       __throw_out_of_range(__N(__s));
00291     return __pos;
00292       }
00293 
00294       // NB: _M_limit doesn't check for a bad __pos value.
00295       size_type
00296       _M_limit(size_type __pos, size_type __off) const
00297       {
00298     const bool __testoff =  __off < this->size() - __pos;
00299     return __testoff ? __off : this->size() - __pos;
00300       }
00301 
00302       // _S_copy_chars is a separate template to permit specialization
00303       // to optimize for the common case of pointers as iterators.
00304       template<class _Iterator>
00305         static void
00306         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00307         {
00308       for (; __k1 != __k2; ++__k1, ++__p)
00309         traits_type::assign(*__p, *__k1); // These types are off.
00310     }
00311 
00312       static void
00313       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
00314       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00315 
00316       static void
00317       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
00318       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00319 
00320       static void
00321       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00322       { traits_type::copy(__p, __k1, __k2 - __k1); }
00323 
00324       static void
00325       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00326       { traits_type::copy(__p, __k1, __k2 - __k1); }
00327 
00328       void
00329       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
00330 
00331       void
00332       _M_leak_hard();
00333 
00334       static _Rep&
00335       _S_empty_rep()
00336       { return _Rep::_S_empty_rep(); }
00337 
00338     public:
00339       // Construct/copy/destroy:
00340       // NB: We overload ctors in some cases instead of using default
00341       // arguments, per 17.4.4.4 para. 2 item 2.
00342 
00346       inline
00347       basic_string();
00348 
00352       explicit
00353       basic_string(const _Alloc& __a);
00354 
00355       // NB: per LWG issue 42, semantics different from IS:
00360       basic_string(const basic_string& __str);
00367       basic_string(const basic_string& __str, size_type __pos,
00368            size_type __n = npos);
00376       basic_string(const basic_string& __str, size_type __pos,
00377            size_type __n, const _Alloc& __a);
00378 
00388       basic_string(const _CharT* __s, size_type __n,
00389            const _Alloc& __a = _Alloc());
00395       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
00402       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
00403 
00410       template<class _InputIterator>
00411         basic_string(_InputIterator __beg, _InputIterator __end,
00412              const _Alloc& __a = _Alloc());
00413 
00417       ~basic_string()
00418       { _M_rep()->_M_dispose(this->get_allocator()); }
00419 
00424       basic_string&
00425       operator=(const basic_string& __str) 
00426       { 
00427     this->assign(__str); 
00428     return *this;
00429       }
00430 
00435       basic_string&
00436       operator=(const _CharT* __s) 
00437       { 
00438     this->assign(__s); 
00439     return *this;
00440       }
00441 
00449       basic_string&
00450       operator=(_CharT __c) 
00451       { 
00452     this->assign(1, __c); 
00453     return *this;
00454       }
00455 
00456       // Iterators:
00461       iterator
00462       begin()
00463       {
00464     _M_leak();
00465     return iterator(_M_data());
00466       }
00467 
00472       const_iterator
00473       begin() const
00474       { return const_iterator(_M_data()); }
00475 
00480       iterator
00481       end()
00482       {
00483     _M_leak();
00484     return iterator(_M_data() + this->size());
00485       }
00486 
00491       const_iterator
00492       end() const
00493       { return const_iterator(_M_data() + this->size()); }
00494 
00500       reverse_iterator
00501       rbegin()
00502       { return reverse_iterator(this->end()); }
00503 
00509       const_reverse_iterator
00510       rbegin() const
00511       { return const_reverse_iterator(this->end()); }
00512 
00518       reverse_iterator
00519       rend()
00520       { return reverse_iterator(this->begin()); }
00521 
00527       const_reverse_iterator
00528       rend() const
00529       { return const_reverse_iterator(this->begin()); }
00530 
00531     public:
00532       // Capacity:
00535       size_type
00536       size() const { return _M_rep()->_M_length; }
00537 
00540       size_type
00541       length() const { return _M_rep()->_M_length; }
00542 
00544       size_type
00545       max_size() const { return _Rep::_S_max_size; }
00546 
00557       void
00558       resize(size_type __n, _CharT __c);
00559 
00570       void
00571       resize(size_type __n) { this->resize(__n, _CharT()); }
00572 
00577       size_type
00578       capacity() const { return _M_rep()->_M_capacity; }
00579 
00597       void
00598       reserve(size_type __res_arg = 0);
00599 
00603       void
00604       clear() { _M_mutate(0, this->size(), 0); }
00605 
00609       bool
00610       empty() const { return this->size() == 0; }
00611 
00612       // Element access:
00623       const_reference
00624       operator[] (size_type __pos) const
00625       {
00626     _GLIBCXX_DEBUG_ASSERT(__pos <= size());
00627     return _M_data()[__pos];
00628       }
00629 
00640       reference
00641       operator[](size_type __pos)
00642       {
00643     _GLIBCXX_DEBUG_ASSERT(__pos < size());
00644     _M_leak();
00645     return _M_data()[__pos];
00646       }
00647 
00658       const_reference
00659       at(size_type __n) const
00660       {
00661     if (__n >= this->size())
00662       __throw_out_of_range(__N("basic_string::at"));
00663     return _M_data()[__n];
00664       }
00665 
00677       reference
00678       at(size_type __n)
00679       {
00680     if (__n >= size())
00681       __throw_out_of_range(__N("basic_string::at"));
00682     _M_leak();
00683     return _M_data()[__n];
00684       }
00685 
00686       // Modifiers:
00692       basic_string&
00693       operator+=(const basic_string& __str) { return this->append(__str); }
00694 
00700       basic_string&
00701       operator+=(const _CharT* __s) { return this->append(__s); }
00702 
00708       basic_string&
00709       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
00710 
00716       basic_string&
00717       append(const basic_string& __str);
00718 
00731       basic_string&
00732       append(const basic_string& __str, size_type __pos, size_type __n);
00733 
00740       basic_string&
00741       append(const _CharT* __s, size_type __n);
00742 
00748       basic_string&
00749       append(const _CharT* __s)
00750       {
00751     __glibcxx_requires_string(__s);
00752     return this->append(__s, traits_type::length(__s));
00753       }
00754 
00763       basic_string&
00764       append(size_type __n, _CharT __c)
00765       { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
00766 
00775       template<class _InputIterator>
00776         basic_string&
00777         append(_InputIterator __first, _InputIterator __last)
00778         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
00779 
00784       void
00785       push_back(_CharT __c)
00786       { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); }
00787 
00793       basic_string&
00794       assign(const basic_string& __str);
00795 
00808       basic_string&
00809       assign(const basic_string& __str, size_type __pos, size_type __n)
00810       { return this->assign(__str._M_data()
00811                 + __str._M_check(__pos, "basic_string::assign"),
00812                 __str._M_limit(__pos, __n)); }
00813 
00824       basic_string&
00825       assign(const _CharT* __s, size_type __n);
00826 
00836       basic_string&
00837       assign(const _CharT* __s)
00838       {
00839     __glibcxx_requires_string(__s);
00840     return this->assign(__s, traits_type::length(__s));
00841       }
00842 
00852       basic_string&
00853       assign(size_type __n, _CharT __c)
00854       { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
00855 
00864       template<class _InputIterator>
00865         basic_string&
00866         assign(_InputIterator __first, _InputIterator __last)
00867         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
00868 
00881       void
00882       insert(iterator __p, size_type __n, _CharT __c)
00883       { this->replace(__p, __p, __n, __c);  }
00884 
00896       template<class _InputIterator>
00897         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
00898         { this->replace(__p, __p, __beg, __end); }
00899 
00911       basic_string&
00912       insert(size_type __pos1, const basic_string& __str)
00913       { return this->insert(__pos1, __str, size_type(0), __str.size()); }
00914 
00933       basic_string&
00934       insert(size_type __pos1, const basic_string& __str,
00935          size_type __pos2, size_type __n)
00936       { return this->insert(__pos1, __str._M_data()
00937                 + __str._M_check(__pos2, "basic_string::insert"),
00938                 __str._M_limit(__pos2, __n)); }
00939 
00956       basic_string&
00957       insert(size_type __pos, const _CharT* __s, size_type __n);
00958 
00974       basic_string&
00975       insert(size_type __pos, const _CharT* __s)
00976       {
00977     __glibcxx_requires_string(__s);
00978     return this->insert(__pos, __s, traits_type::length(__s));
00979       }
00980 
00997       basic_string&
00998       insert(size_type __pos, size_type __n, _CharT __c)
00999       { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
01000                   size_type(0), __n, __c); }
01001 
01014       iterator
01015       insert(iterator __p, _CharT __c)
01016       {
01017     _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
01018     const size_type __pos = __p - _M_ibegin();
01019     _M_replace_aux(__pos, size_type(0), size_type(1), __c);
01020     _M_rep()->_M_set_leaked();
01021     return this->_M_ibegin() + __pos;
01022       }
01023 
01038       basic_string&
01039       erase(size_type __pos = 0, size_type __n = npos)
01040       { return _M_replace_safe(_M_check(__pos, "basic_string::erase"),
01041                    _M_limit(__pos, __n), NULL, size_type(0)); }
01042 
01051       iterator
01052       erase(iterator __position)
01053       {
01054     _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
01055                  && __position < _M_iend());
01056     const size_type __pos = __position - _M_ibegin();
01057     _M_replace_safe(__pos, size_type(1), NULL, size_type(0));
01058     _M_rep()->_M_set_leaked();
01059     return _M_ibegin() + __pos;
01060       }
01061 
01071       iterator
01072       erase(iterator __first, iterator __last)
01073       {
01074     _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
01075                  && __last <= _M_iend());
01076         const size_type __pos = __first - _M_ibegin();
01077     _M_replace_safe(__pos, __last - __first, NULL, size_type(0));
01078     _M_rep()->_M_set_leaked();
01079     return _M_ibegin() + __pos;
01080       }
01081 
01098       basic_string&
01099       replace(size_type __pos, size_type __n, const basic_string& __str)
01100       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
01101 
01120       basic_string&
01121       replace(size_type __pos1, size_type __n1, const basic_string& __str,
01122           size_type __pos2, size_type __n2)
01123       { return this->replace(__pos1, __n1, __str._M_data()
01124                  + __str._M_check(__pos2, "basic_string::replace"),
01125                  __str._M_limit(__pos2, __n2)); }
01126 
01144       basic_string&
01145       replace(size_type __pos, size_type __n1, const _CharT* __s,
01146           size_type __n2);
01147 
01163       basic_string&
01164       replace(size_type __pos, size_type __n1, const _CharT* __s)
01165       {
01166     __glibcxx_requires_string(__s);
01167     return this->replace(__pos, __n1, __s, traits_type::length(__s));
01168       }
01169 
01186       basic_string&
01187       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
01188       { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
01189                   _M_limit(__pos, __n1), __n2, __c); }
01190 
01204       basic_string&
01205       replace(iterator __i1, iterator __i2, const basic_string& __str)
01206       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
01207 
01222       basic_string&
01223       replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
01224       {
01225     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01226                  && __i2 <= _M_iend());
01227     return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
01228       }
01229 
01243       basic_string&
01244       replace(iterator __i1, iterator __i2, const _CharT* __s)
01245       {
01246     __glibcxx_requires_string(__s);
01247     return this->replace(__i1, __i2, __s, traits_type::length(__s));
01248       }
01249 
01264       basic_string&
01265       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
01266       {
01267     _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01268                  && __i2 <= _M_iend());
01269     return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
01270       }
01271 
01286       template<class _InputIterator>
01287         basic_string&
01288         replace(iterator __i1, iterator __i2,
01289         _InputIterator __k1, _InputIterator __k2)
01290         {
01291       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01292                    && __i2 <= _M_iend());
01293       __glibcxx_requires_valid_range(__k1, __k2);
01294       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
01295       return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
01296     }
01297 
01298       // Specializations for the common case of pointer and iterator:
01299       // useful to avoid the overhead of temporary buffering in _M_replace.
01300       basic_string&
01301         replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
01302         {
01303       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01304                    && __i2 <= _M_iend());
01305       __glibcxx_requires_valid_range(__k1, __k2);
01306       return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01307                    __k1, __k2 - __k1);
01308     }
01309 
01310       basic_string&
01311         replace(iterator __i1, iterator __i2,
01312         const _CharT* __k1, const _CharT* __k2)
01313         {
01314       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01315                    && __i2 <= _M_iend());
01316       __glibcxx_requires_valid_range(__k1, __k2);
01317       return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01318                    __k1, __k2 - __k1);
01319     }
01320 
01321       basic_string&
01322         replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
01323         {
01324       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01325                    && __i2 <= _M_iend());
01326       __glibcxx_requires_valid_range(__k1, __k2);
01327       return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01328                    __k1.base(), __k2 - __k1);
01329     }
01330 
01331       basic_string&
01332         replace(iterator __i1, iterator __i2,
01333         const_iterator __k1, const_iterator __k2)
01334         {
01335       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
01336                    && __i2 <= _M_iend());
01337       __glibcxx_requires_valid_range(__k1, __k2);
01338       return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
01339                    __k1.base(), __k2 - __k1);
01340     }
01341 
01342     private:
01343       template<class _Integer>
01344     basic_string&
01345     _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
01346                 _Integer __val, __true_type)
01347         { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
01348 
01349       template<class _InputIterator>
01350     basic_string&
01351     _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
01352                 _InputIterator __k2, __false_type);
01353 
01354       basic_string&
01355       _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
01356              _CharT __c)
01357       {
01358     if (this->max_size() - (this->size() - __n1) < __n2)
01359       __throw_length_error(__N("basic_string::_M_replace_aux"));
01360     _M_mutate(__pos1, __n1, __n2);
01361     if (__n2 == 1)
01362       _M_data()[__pos1] = __c;
01363     else if (__n2)
01364       traits_type::assign(_M_data() + __pos1, __n2, __c);
01365     return *this;
01366       }
01367 
01368       basic_string&
01369       _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
01370               size_type __n2)
01371       {
01372     _M_mutate(__pos1, __n1, __n2);
01373     if (__n2 == 1)
01374       _M_data()[__pos1] = *__s;
01375     else if (__n2)
01376       traits_type::copy(_M_data() + __pos1, __s, __n2);
01377     return *this;
01378       }
01379 
01380       // _S_construct_aux is used to implement the 21.3.1 para 15 which
01381       // requires special behaviour if _InIter is an integral type
01382       template<class _InIterator>
01383         static _CharT*
01384         _S_construct_aux(_InIterator __beg, _InIterator __end,
01385              const _Alloc& __a, __false_type)
01386     {
01387           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
01388           return _S_construct(__beg, __end, __a, _Tag());
01389     }
01390 
01391       template<class _InIterator>
01392         static _CharT*
01393         _S_construct_aux(_InIterator __beg, _InIterator __end,
01394              const _Alloc& __a, __true_type)
01395     { return _S_construct(static_cast<size_type>(__beg),
01396                   static_cast<value_type>(__end), __a); }
01397 
01398       template<class _InIterator>
01399         static _CharT*
01400         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
01401     {
01402       typedef typename _Is_integer<_InIterator>::_Integral _Integral;
01403       return _S_construct_aux(__beg, __end, __a, _Integral());
01404         }
01405 
01406       // For Input Iterators, used in istreambuf_iterators, etc.
01407       template<class _InIterator>
01408         static _CharT*
01409          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
01410               input_iterator_tag);
01411 
01412       // For forward_iterators up to random_access_iterators, used for
01413       // string::iterator, _CharT*, etc.
01414       template<class _FwdIterator>
01415         static _CharT*
01416         _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
01417              forward_iterator_tag);
01418 
01419       static _CharT*
01420       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
01421 
01422     public:
01423 
01435       size_type
01436       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
01437 
01445       void
01446       swap(basic_string& __s);
01447 
01448       // String operations:
01455       const _CharT*
01456       c_str() const { return _M_data(); }
01457 
01464       const _CharT*
01465       data() const { return _M_data(); }
01466 
01470       allocator_type
01471       get_allocator() const { return _M_dataplus; }
01472 
01484       size_type
01485       find(const _CharT* __s, size_type __pos, size_type __n) const;
01486 
01497       size_type
01498       find(const basic_string& __str, size_type __pos = 0) const
01499       { return this->find(__str.data(), __pos, __str.size()); }
01500 
01511       size_type
01512       find(const _CharT* __s, size_type __pos = 0) const
01513       {
01514     __glibcxx_requires_string(__s);
01515     return this->find(__s, __pos, traits_type::length(__s));
01516       }
01517 
01528       size_type
01529       find(_CharT __c, size_type __pos = 0) const;
01530 
01541       size_type
01542       rfind(const basic_string& __str, size_type __pos = npos) const
01543       { return this->rfind(__str.data(), __pos, __str.size()); }
01544 
01556       size_type
01557       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
01558 
01569       size_type
01570       rfind(const _CharT* __s, size_type __pos = npos) const
01571       {
01572     __glibcxx_requires_string(__s);
01573     return this->rfind(__s, __pos, traits_type::length(__s));
01574       }
01575 
01586       size_type
01587       rfind(_CharT __c, size_type __pos = npos) const;
01588 
01599       size_type
01600       find_first_of(const basic_string& __str, size_type __pos = 0) const
01601       { return this->find_first_of(__str.data(), __pos, __str.size()); }
01602 
01614       size_type
01615       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
01616 
01627       size_type
01628       find_first_of(const _CharT* __s, size_type __pos = 0) const
01629       {
01630     __glibcxx_requires_string(__s);
01631     return this->find_first_of(__s, __pos, traits_type::length(__s));
01632       }
01633 
01646       size_type
01647       find_first_of(_CharT __c, size_type __pos = 0) const
01648       { return this->find(__c, __pos); }
01649 
01660       size_type
01661       find_last_of(const basic_string& __str, size_type __pos = npos) const
01662       { return this->find_last_of(__str.data(), __pos, __str.size()); }
01663 
01675       size_type
01676       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
01677 
01688       size_type
01689       find_last_of(const _CharT* __s, size_type __pos = npos) const
01690       {
01691     __glibcxx_requires_string(__s);
01692     return this->find_last_of(__s, __pos, traits_type::length(__s));
01693       }
01694 
01707       size_type
01708       find_last_of(_CharT __c, size_type __pos = npos) const
01709       { return this->rfind(__c, __pos); }
01710 
01721       size_type
01722       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
01723       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
01724 
01736       size_type
01737       find_first_not_of(const _CharT* __s, size_type __pos,
01738             size_type __n) const;
01739 
01750       size_type
01751       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
01752       {
01753     __glibcxx_requires_string(__s);
01754     return this->find_first_not_of(__s, __pos, traits_type::length(__s));
01755       }
01756 
01767       size_type
01768       find_first_not_of(_CharT __c, size_type __pos = 0) const;
01769 
01780       size_type
01781       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
01782       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
01783 
01796       size_type
01797       find_last_not_of(const _CharT* __s, size_type __pos,
01798                size_type __n) const;
01809       size_type
01810       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
01811       {
01812     __glibcxx_requires_string(__s);
01813     return this->find_last_not_of(__s, __pos, traits_type::length(__s));
01814       }
01815 
01826       size_type
01827       find_last_not_of(_CharT __c, size_type __pos = npos) const;
01828 
01841       basic_string
01842       substr(size_type __pos = 0, size_type __n = npos) const
01843       { return basic_string(*this,
01844                 _M_check(__pos, "basic_string::substr"), __n); }
01845 
01859       int
01860       compare(const basic_string& __str) const
01861       {
01862     const size_type __size = this->size();
01863     const size_type __osize = __str.size();
01864     const size_type __len = std::min(__size, __osize);
01865 
01866     int __r = traits_type::compare(_M_data(), __str.data(), __len);
01867     if (!__r)
01868       __r =  __size - __osize;
01869     return __r;
01870       }
01871 
01889       int
01890       compare(size_type __pos, size_type __n, const basic_string& __str) const;
01891 
01913       int
01914       compare(size_type __pos1, size_type __n1, const basic_string& __str,
01915           size_type __pos2, size_type __n2) const;
01916 
01931       int
01932       compare(const _CharT* __s) const;
01933 
01934       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01935       // 5 String::compare specification questionable
01954       int
01955       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
01956 
01979       int
01980       compare(size_type __pos, size_type __n1, const _CharT* __s,
01981           size_type __n2) const;
01982   };
01983 
01984   template<typename _CharT, typename _Traits, typename _Alloc>
01985     inline basic_string<_CharT, _Traits, _Alloc>::
01986     basic_string()
01987 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
01988     : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
01989 #else
01990     : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
01991 #endif
01992 
01993   // operator+
02000   template<typename _CharT, typename _Traits, typename _Alloc>
02001     basic_string<_CharT, _Traits, _Alloc>
02002     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02003           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02004     {
02005       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
02006       __str.append(__rhs);
02007       return __str;
02008     }
02009 
02016   template<typename _CharT, typename _Traits, typename _Alloc>
02017     basic_string<_CharT,_Traits,_Alloc>
02018     operator+(const _CharT* __lhs,
02019           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
02020 
02027   template<typename _CharT, typename _Traits, typename _Alloc>
02028     basic_string<_CharT,_Traits,_Alloc>
02029     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
02030 
02037   template<typename _CharT, typename _Traits, typename _Alloc>
02038     inline basic_string<_CharT, _Traits, _Alloc>
02039     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02040          const _CharT* __rhs)
02041     {
02042       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
02043       __str.append(__rhs);
02044       return __str;
02045     }
02046 
02053   template<typename _CharT, typename _Traits, typename _Alloc>
02054     inline basic_string<_CharT, _Traits, _Alloc>
02055     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
02056     {
02057       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
02058       typedef typename __string_type::size_type     __size_type;
02059       __string_type __str(__lhs);
02060       __str.append(__size_type(1), __rhs);
02061       return __str;
02062     }
02063 
02064   // operator ==
02071   template<typename _CharT, typename _Traits, typename _Alloc>
02072     inline bool
02073     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02074            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02075     { return __lhs.compare(__rhs) == 0; }
02076 
02083   template<typename _CharT, typename _Traits, typename _Alloc>
02084     inline bool
02085     operator==(const _CharT* __lhs,
02086            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02087     { return __rhs.compare(__lhs) == 0; }
02088 
02095   template<typename _CharT, typename _Traits, typename _Alloc>
02096     inline bool
02097     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02098            const _CharT* __rhs)
02099     { return __lhs.compare(__rhs) == 0; }
02100 
02101   // operator !=
02108   template<typename _CharT, typename _Traits, typename _Alloc>
02109     inline bool
02110     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02111            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02112     { return __rhs.compare(__lhs) != 0; }
02113 
02120   template<typename _CharT, typename _Traits, typename _Alloc>
02121     inline bool
02122     operator!=(const _CharT* __lhs,
02123            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02124     { return __rhs.compare(__lhs) != 0; }
02125 
02132   template<typename _CharT, typename _Traits, typename _Alloc>
02133     inline bool
02134     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02135            const _CharT* __rhs)
02136     { return __lhs.compare(__rhs) != 0; }
02137 
02138   // operator <
02145   template<typename _CharT, typename _Traits, typename _Alloc>
02146     inline bool
02147     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02148           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02149     { return __lhs.compare(__rhs) < 0; }
02150 
02157   template<typename _CharT, typename _Traits, typename _Alloc>
02158     inline bool
02159     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02160           const _CharT* __rhs)
02161     { return __lhs.compare(__rhs) < 0; }
02162 
02169   template<typename _CharT, typename _Traits, typename _Alloc>
02170     inline bool
02171     operator<(const _CharT* __lhs,
02172           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02173     { return __rhs.compare(__lhs) > 0; }
02174 
02175   // operator >
02182   template<typename _CharT, typename _Traits, typename _Alloc>
02183     inline bool
02184     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02185           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02186     { return __lhs.compare(__rhs) > 0; }
02187 
02194   template<typename _CharT, typename _Traits, typename _Alloc>
02195     inline bool
02196     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02197           const _CharT* __rhs)
02198     { return __lhs.compare(__rhs) > 0; }
02199 
02206   template<typename _CharT, typename _Traits, typename _Alloc>
02207     inline bool
02208     operator>(const _CharT* __lhs,
02209           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02210     { return __rhs.compare(__lhs) < 0; }
02211 
02212   // operator <=
02219   template<typename _CharT, typename _Traits, typename _Alloc>
02220     inline bool
02221     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02222            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02223     { return __lhs.compare(__rhs) <= 0; }
02224 
02231   template<typename _CharT, typename _Traits, typename _Alloc>
02232     inline bool
02233     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02234            const _CharT* __rhs)
02235     { return __lhs.compare(__rhs) <= 0; }
02236 
02243   template<typename _CharT, typename _Traits, typename _Alloc>
02244     inline bool
02245     operator<=(const _CharT* __lhs,
02246            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02247   { return __rhs.compare(__lhs) >= 0; }
02248 
02249   // operator >=
02256   template<typename _CharT, typename _Traits, typename _Alloc>
02257     inline bool
02258     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02259            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02260     { return __lhs.compare(__rhs) >= 0; }
02261 
02268   template<typename _CharT, typename _Traits, typename _Alloc>
02269     inline bool
02270     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
02271            const _CharT* __rhs)
02272     { return __lhs.compare(__rhs) >= 0; }
02273 
02280   template<typename _CharT, typename _Traits, typename _Alloc>
02281     inline bool
02282     operator>=(const _CharT* __lhs,
02283          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
02284     { return __rhs.compare(__lhs) <= 0; }
02285 
02293   template<typename _CharT, typename _Traits, typename _Alloc>
02294     inline void
02295     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
02296      basic_string<_CharT, _Traits, _Alloc>& __rhs)
02297     { __lhs.swap(__rhs); }
02298 
02310   template<typename _CharT, typename _Traits, typename _Alloc>
02311     basic_istream<_CharT, _Traits>&
02312     operator>>(basic_istream<_CharT, _Traits>& __is,
02313            basic_string<_CharT, _Traits, _Alloc>& __str);
02314 
02324   template<typename _CharT, typename _Traits, typename _Alloc>
02325     basic_ostream<_CharT, _Traits>&
02326     operator<<(basic_ostream<_CharT, _Traits>& __os,
02327            const basic_string<_CharT, _Traits, _Alloc>& __str);
02328 
02342   template<typename _CharT, typename _Traits, typename _Alloc>
02343     basic_istream<_CharT,_Traits>&
02344     getline(basic_istream<_CharT, _Traits>& __is,
02345         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
02346 
02359   template<typename _CharT, typename _Traits, typename _Alloc>
02360     inline basic_istream<_CharT,_Traits>&
02361     getline(basic_istream<_CharT, _Traits>& __is,
02362         basic_string<_CharT, _Traits, _Alloc>& __str);
02363 } // namespace std
02364 
02365 #endif /* _BASIC_STRING_H */

Generated on Tue Jan 30 17:31:46 2007 for GNU C++ STL by doxygen 1.3.6