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, 2005, 2006
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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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       typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
00113 
00114       // Types:
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       // _Rep: string representation
00133       //   Invariants:
00134       //   1. String really contains _M_length + 1 characters: due to 21.3.4
00135       //      must be kept null-terminated.
00136       //   2. _M_capacity >= _M_length
00137       //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
00138       //   3. _M_refcount has three states:
00139       //      -1: leaked, one reference, no ref-copies allowed, non-const.
00140       //       0: one reference, non-const.
00141       //     n>0: n + 1 references, operations require a lock, const.
00142       //   4. All fields==0 is an empty string, given the extra storage
00143       //      beyond-the-end for a null terminator; thus, the shared
00144       //      empty string representation needs no constructor.
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     // Types:
00156     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
00157 
00158     // (Public) Data members:
00159 
00160     // The maximum number of individual char_type elements of an
00161     // individual string is determined by _S_max_size. This is the
00162     // value that will be returned by max_size().  (Whereas npos
00163     // is the maximum number of bytes the allocator can allocate.)
00164     // If one was to divvy up the theoretical largest size string,
00165     // with a terminating character and m _CharT elements, it'd
00166     // look like this:
00167     // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
00168     // Solving for m:
00169     // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
00170     // In addition, this implementation quarters this amount.
00171     static const size_type  _S_max_size;
00172     static const _CharT _S_terminal;
00173 
00174     // The following storage is init'd to 0 by the linker, resulting
00175         // (carefully) in an empty string with one reference.
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();  // One reference.
00205       this->_M_length = __n;
00206       traits_type::assign(this->_M_refdata()[__n], _S_terminal);
00207       // grrr. (per 21.3.4)
00208       // You cannot leave those LWG people alone for a second.
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     // Create & Destroy
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     }  // XXX MT
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     }  // XXX MT
00248 
00249     _CharT*
00250     _M_clone(const _Alloc&, size_type __res = 0);
00251       };
00252 
00253       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
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; // The actual data.
00260       };
00261 
00262     public:
00263       // Data Members (public):
00264       // NB: This is an unsigned type, and thus represents the maximum
00265       // size that the allocator can hold.
00267       static const size_type    npos = static_cast<size_type>(-1);
00268 
00269     private:
00270       // Data Members (private):
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       // For the internal use we have functions similar to `begin'/`end'
00286       // but they do not call _M_leak.
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()    // for use in begin() & non-const op[]
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       // NB: _M_limit doesn't check for a bad __pos value.
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       // True if _Rep and source do not overlap.
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       // When __n = 1 way faster than the general multichar
00334       // traits_type::copy/move/assign.
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       // _S_copy_chars is a separate template to permit specialization
00363       // to optimize for the common case of pointers as iterators.
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); // These types are off.
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       // Construct/copy/destroy:
00400       // NB: We overload ctors in some cases instead of using default
00401       // arguments, per 17.4.4.4 para. 2 item 2.
00402 
00406       inline
00407       basic_string();
00408 
00412       explicit
00413       basic_string(const _Alloc& __a);
00414 
00415       // NB: per LWG issue 42, semantics different from IS:
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       // Iterators:
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       // Capacity:
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       // Element access:
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         // allow pos == size() as v3 extension:
00705     _GLIBCXX_DEBUG_ASSERT(__pos <= size());
00706         // but be strict in pedantic mode:
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       // Modifiers:
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       // Specializations for the common case of pointer and iterator:
01378       // useful to avoid the overhead of temporary buffering in _M_replace.
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       // _S_construct_aux is used to implement the 21.3.1 para 15 which
01442       // requires special behaviour if _InIter is an integral type
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       // For Input Iterators, used in istreambuf_iterators, etc.
01468       template<class _InIterator>
01469         static _CharT*
01470          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
01471               input_iterator_tag);
01472 
01473       // For forward_iterators up to random_access_iterators, used for
01474       // string::iterator, _CharT*, etc.
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       // String operations:
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       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01999       // 5 String::compare specification questionable
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   // operator+
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   // operator ==
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   // operator !=
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   // operator <
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   // operator >
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   // operator <=
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   // operator >=
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 } // namespace std
02444 
02445 #endif /* _BASIC_STRING_H */

Generated on Tue Feb 2 16:55:45 2010 for GNU C++ STL by  doxygen 1.4.7