# 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       basic_string&
    00505       assign(const _CharT* __s, size_type __n);
    00506
    00507       basic_string&
    00508       assign(const _CharT* __s)
    00509       { return this->assign(__s, traits_type::length(__s)); }
    00510
    00511       basic_string&
    00512       assign(size_type __n, _CharT __c)
    00513       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
    00514
    00515       template<class _InputIterator>
    00516         basic_string&
    00517         assign(_InputIterator __first, _InputIterator __last)
    00518         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
    00519
    00520       void
    00521       insert(iterator __p, size_type __n, _CharT __c)
    00522       { this->replace(__p, __p, __n, __c);  }
    00523
    00524       template<class _InputIterator>
    00525         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
    00526         { this->replace(__p, __p, __beg, __end); }
    00527
    00528       basic_string&
    00529       insert(size_type __pos1, const basic_string& __str)
    00530       { return this->insert(__pos1, __str, 0, __str.size()); }
    00531
    00532       basic_string&
    00533       insert(size_type __pos1, const basic_string& __str,
    00534          size_type __pos2, size_type __n);
    00535
    00536       basic_string&
    00537       insert(size_type __pos, const _CharT* __s, size_type __n);
    00538
    00539       basic_string&
    00540       insert(size_type __pos, const _CharT* __s)
    00541       { return this->insert(__pos, __s, traits_type::length(__s)); }
    00542
    00543       basic_string&
    00544       insert(size_type __pos, size_type __n, _CharT __c)
    00545       {
    00546     this->insert(_M_check(__pos), __n, __c);
    00547     return *this;
    00548       }
    00549
    00550       iterator
    00551       insert(iterator __p, _CharT __c = _CharT())
    00552       {
    00553     size_type __pos = __p - _M_ibegin();
    00554     this->insert(_M_check(__pos), size_type(1), __c);
    00555     _M_rep()->_M_set_leaked();
    00556     return this->_M_ibegin() + __pos;
    00557       }
    00558
    00559       basic_string&
    00560       erase(size_type __pos = 0, size_type __n = npos)
    00561       {
    00562     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
    00563                  _M_data(), _M_data());
    00564       }
    00565
    00566       iterator
    00567       erase(iterator __position)
    00568       {
    00569     size_type __i = __position - _M_ibegin();
    00570         this->replace(__position, __position + 1, _M_data(), _M_data());
    00571     _M_rep()->_M_set_leaked();
    00572     return _M_ibegin() + __i;
    00573       }
    00574
    00575       iterator
    00576       erase(iterator __first, iterator __last)
    00577       {
    00578         size_type __i = __first - _M_ibegin();
    00579     this->replace(__first, __last, _M_data(), _M_data());
    00580     _M_rep()->_M_set_leaked();
    00581        return _M_ibegin() + __i;
    00582       }
    00583
    00584       basic_string&
    00585       replace(size_type __pos, size_type __n, const basic_string& __str)
    00586       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
    00587
    00588       basic_string&
    00589       replace(size_type __pos1, size_type __n1, const basic_string& __str,
    00590           size_type __pos2, size_type __n2);
    00591
    00592       basic_string&
    00593       replace(size_type __pos, size_type __n1, const _CharT* __s,
    00594           size_type __n2);
    00595
    00596       basic_string&
    00597       replace(size_type __pos, size_type __n1, const _CharT* __s)
    00598       { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
    00599
    00600       basic_string&
    00601       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
    00602       { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
    00603
    00604       basic_string&
    00605       replace(iterator __i1, iterator __i2, const basic_string& __str)
    00606       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
    00607
    00608       basic_string&
    00609       replace(iterator __i1, iterator __i2,
    00610                            const _CharT* __s, size_type __n)
    00611       { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
    00612
    00613       basic_string&
    00614       replace(iterator __i1, iterator __i2, const _CharT* __s)
    00615       { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
    00616
    00617       basic_string&
    00618       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
    00619
    00620       template<class _InputIterator>
    00621         basic_string&
    00622         replace(iterator __i1, iterator __i2,
    00623         _InputIterator __k1, _InputIterator __k2)
    00624         { return _M_replace(__i1, __i2, __k1, __k2,
    00625          typename iterator_traits<_InputIterator>::iterator_category()); }
    00626
    00627       // Specializations for the common case of pointer and iterator:
    00628       // useful to avoid the overhead of temporary buffering in _M_replace.
    00629       basic_string&
    00630       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
    00631         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
    00632                    __k1, __k2 - __k1); }
    00633
    00634       basic_string&
    00635       replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
    00636         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
    00637                    __k1, __k2 - __k1); }
    00638
    00639       basic_string&
    00640       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
    00641         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
    00642                    __k1.base(), __k2 - __k1);
    00643     }
    00644
    00645       basic_string&
    00646       replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
    00647         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
    00648                    __k1.base(), __k2 - __k1);
    00649     }
    00650
    00651     private:
    00652       template<class _InputIterator>
    00653         basic_string&
    00654         _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
    00655            _InputIterator __k2, input_iterator_tag);
    00656
    00657       template<class _ForwardIterator>
    00658         basic_string&
    00659         _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
    00660            _ForwardIterator __k2);
    00661
    00662       // _S_construct_aux is used to implement the 21.3.1 para 15 which
    00663       // requires special behaviour if _InIter is an integral type
    00664       template<class _InIter>
    00665         static _CharT*
    00666         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
    00667              __false_type)
    00668     {
    00669           typedef typename iterator_traits<_InIter>::iterator_category _Tag;
    00670           return _S_construct(__beg, __end, __a, _Tag());
    00671     }
    00672
    00673       template<class _InIter>
    00674         static _CharT*
    00675         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
    00676              __true_type)
    00677     {
    00678       return _S_construct(static_cast<size_type>(__beg),
    00679                   static_cast<value_type>(__end), __a);
    00680     }
    00681
    00682       template<class _InIter>
    00683         static _CharT*
    00684         _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
    00685     {
    00686       typedef typename _Is_integer<_InIter>::_Integral _Integral;
    00687       return _S_construct_aux(__beg, __end, __a, _Integral());
    00688         }
    00689
    00690       // For Input Iterators, used in istreambuf_iterators, etc.
    00691       template<class _InIter>
    00692         static _CharT*
    00693          _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
    00694               input_iterator_tag);
    00695
    00696       // For forward_iterators up to random_access_iterators, used for
    00697       // string::iterator, _CharT*, etc.
    00698       template<class _FwdIter>
    00699         static _CharT*
    00700         _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
    00701              forward_iterator_tag);
    00702
    00703       static _CharT*
    00704       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
    00705
    00706     public:
    00707
    00708       size_type
    00709       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
    00710
    00711       void
    00712       swap(basic_string<_CharT, _Traits, _Alloc>& __s);
    00713
    00714       // String operations:
    00715       const _CharT*
    00716       c_str() const
    00717       {
    00718     // MT: This assumes concurrent writes are OK.
    00719     size_type __n = this->size();
    00720     traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
    00721         return _M_data();
    00722       }
    00723
    00724       const _CharT*
    00725       data() const { return _M_data(); }
    00726
    00727       allocator_type
    00728       get_allocator() const { return _M_dataplus; }
    00729
    00730       size_type
    00731       find(const _CharT* __s, size_type __pos, size_type __n) const;
    00732
    00733       size_type
    00734       find(const basic_string& __str, size_type __pos = 0) const
    00735       { return this->find(__str.data(), __pos, __str.size()); }
    00736
    00737       size_type
    00738       find(const _CharT* __s, size_type __pos = 0) const
    00739       { return this->find(__s, __pos, traits_type::length(__s)); }
    00740
    00741       size_type
    00742       find(_CharT __c, size_type __pos = 0) const;
    00743
    00744       size_type
    00745       rfind(const basic_string& __str, size_type __pos = npos) const
    00746       { return this->rfind(__str.data(), __pos, __str.size()); }
    00747
    00748       size_type
    00749       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
    00750
    00751       size_type
    00752       rfind(const _CharT* __s, size_type __pos = npos) const
    00753       { return this->rfind(__s, __pos, traits_type::length(__s)); }
    00754
    00755       size_type
    00756       rfind(_CharT __c, size_type __pos = npos) const;
    00757
    00758       size_type
    00759       find_first_of(const basic_string& __str, size_type __pos = 0) const
    00760       { return this->find_first_of(__str.data(), __pos, __str.size()); }
    00761
    00762       size_type
    00763       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
    00764
    00765       size_type
    00766       find_first_of(const _CharT* __s, size_type __pos = 0) const
    00767       { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
    00768
    00769       size_type
    00770       find_first_of(_CharT __c, size_type __pos = 0) const
    00771       { return this->find(__c, __pos); }
    00772
    00773       size_type
    00774       find_last_of(const basic_string& __str, size_type __pos = npos) const
    00775       { return this->find_last_of(__str.data(), __pos, __str.size()); }
    00776
    00777       size_type
    00778       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
    00779
    00780       size_type
    00781       find_last_of(const _CharT* __s, size_type __pos = npos) const
    00782       { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
    00783
    00784       size_type
    00785       find_last_of(_CharT __c, size_type __pos = npos) const
    00786       { return this->rfind(__c, __pos); }
    00787
    00788       size_type
    00789       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
    00790       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
    00791
    00792       size_type
    00793       find_first_not_of(const _CharT* __s, size_type __pos,
    00794             size_type __n) const;
    00795
    00796       size_type
    00797       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
    00798       { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
    00799
    00800       size_type
    00801       find_first_not_of(_CharT __c, size_type __pos = 0) const;
    00802
    00803       size_type
    00804       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
    00805       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
    00806
    00807       size_type
    00808       find_last_not_of(const _CharT* __s, size_type __pos,
    00809                size_type __n) const;
    00810       size_type
    00811       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
    00812       { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
    00813
    00814       size_type
    00815       find_last_not_of(_CharT __c, size_type __pos = npos) const;
    00816
    00817       basic_string
    00818       substr(size_type __pos = 0, size_type __n = npos) const
    00819       {
    00820     if (__pos > this->size())
    00821       __throw_out_of_range("basic_string::substr");
    00822     return basic_string(*this, __pos, __n);
    00823       }
    00824
    00825       int
    00826       compare(const basic_string& __str) const
    00827       {
    00828     size_type __size = this->size();
    00829     size_type __osize = __str.size();
    00830     size_type __len = std::min(__size, __osize);
    00831
    00832     int __r = traits_type::compare(_M_data(), __str.data(), __len);
    00833     if (!__r)
    00834       __r =  __size - __osize;
    00835     return __r;
    00836       }
    00837
    00838       int
    00839       compare(size_type __pos, size_type __n, const basic_string& __str) const;
    00840
    00841       int
    00842       compare(size_type __pos1, size_type __n1, const basic_string& __str,
    00843           size_type __pos2, size_type __n2) const;
    00844
    00845       int
    00846       compare(const _CharT* __s) const;
    00847
    00848       // _GLIBCPP_RESOLVE_LIB_DEFECTS
    00849       // 5. String::compare specification questionable
    00850       int
    00851       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
    00852
    00853       int
    00854       compare(size_type __pos, size_type __n1, const _CharT* __s,
    00855           size_type __n2) const;
    00856   };
    00857
    00858
    00859   template<typename _CharT, typename _Traits, typename _Alloc>
    00860     inline basic_string<_CharT, _Traits, _Alloc>::
    00861     basic_string()
    00862     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
    00863
    00864   // operator+
    00865   template<typename _CharT, typename _Traits, typename _Alloc>
    00866     basic_string<_CharT, _Traits, _Alloc>
    00867     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00868           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00869     {
    00870       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
    00871       __str.append(__rhs);
    00872       return __str;
    00873     }
    00874
    00875   template<typename _CharT, typename _Traits, typename _Alloc>
    00876     basic_string<_CharT,_Traits,_Alloc>
    00877     operator+(const _CharT* __lhs,
    00878           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
    00879
    00880   template<typename _CharT, typename _Traits, typename _Alloc>
    00881     basic_string<_CharT,_Traits,_Alloc>
    00882     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
    00883
    00884   template<typename _CharT, typename _Traits, typename _Alloc>
    00885     inline basic_string<_CharT, _Traits, _Alloc>
    00886     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00887          const _CharT* __rhs)
    00888     {
    00889       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
    00890       __str.append(__rhs);
    00891       return __str;
    00892     }
    00893
    00894   template<typename _CharT, typename _Traits, typename _Alloc>
    00895     inline basic_string<_CharT, _Traits, _Alloc>
    00896     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
    00897     {
    00898       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
    00899       typedef typename __string_type::size_type     __size_type;
    00900       __string_type __str(__lhs);
    00901       __str.append(__size_type(1), __rhs);
    00902       return __str;
    00903     }
    00904
    00905   // operator ==
    00906   template<typename _CharT, typename _Traits, typename _Alloc>
    00907     inline bool
    00908     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00909            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00910     { return __lhs.compare(__rhs) == 0; }
    00911
    00912   template<typename _CharT, typename _Traits, typename _Alloc>
    00913     inline bool
    00914     operator==(const _CharT* __lhs,
    00915            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00916     { return __rhs.compare(__lhs) == 0; }
    00917
    00918   template<typename _CharT, typename _Traits, typename _Alloc>
    00919     inline bool
    00920     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00921            const _CharT* __rhs)
    00922     { return __lhs.compare(__rhs) == 0; }
    00923
    00924   // operator !=
    00925   template<typename _CharT, typename _Traits, typename _Alloc>
    00926     inline bool
    00927     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00928            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00929     { return __rhs.compare(__lhs) != 0; }
    00930
    00931   template<typename _CharT, typename _Traits, typename _Alloc>
    00932     inline bool
    00933     operator!=(const _CharT* __lhs,
    00934            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00935     { return __rhs.compare(__lhs) != 0; }
    00936
    00937   template<typename _CharT, typename _Traits, typename _Alloc>
    00938     inline bool
    00939     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00940            const _CharT* __rhs)
    00941     { return __lhs.compare(__rhs) != 0; }
    00942
    00943   // operator <
    00944   template<typename _CharT, typename _Traits, typename _Alloc>
    00945     inline bool
    00946     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00947           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00948     { return __lhs.compare(__rhs) < 0; }
    00949
    00950   template<typename _CharT, typename _Traits, typename _Alloc>
    00951     inline bool
    00952     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00953           const _CharT* __rhs)
    00954     { return __lhs.compare(__rhs) < 0; }
    00955
    00956   template<typename _CharT, typename _Traits, typename _Alloc>
    00957     inline bool
    00958     operator<(const _CharT* __lhs,
    00959           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00960     { return __rhs.compare(__lhs) > 0; }
    00961
    00962   // operator >
    00963   template<typename _CharT, typename _Traits, typename _Alloc>
    00964     inline bool
    00965     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00966           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00967     { return __lhs.compare(__rhs) > 0; }
    00968
    00969   template<typename _CharT, typename _Traits, typename _Alloc>
    00970     inline bool
    00971     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00972           const _CharT* __rhs)
    00973     { return __lhs.compare(__rhs) > 0; }
    00974
    00975   template<typename _CharT, typename _Traits, typename _Alloc>
    00976     inline bool
    00977     operator>(const _CharT* __lhs,
    00978           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00979     { return __rhs.compare(__lhs) < 0; }
    00980
    00981   // operator <=
    00982   template<typename _CharT, typename _Traits, typename _Alloc>
    00983     inline bool
    00984     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00985            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00986     { return __lhs.compare(__rhs) <= 0; }
    00987
    00988   template<typename _CharT, typename _Traits, typename _Alloc>
    00989     inline bool
    00990     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    00991            const _CharT* __rhs)
    00992     { return __lhs.compare(__rhs) <= 0; }
    00993
    00994   template<typename _CharT, typename _Traits, typename _Alloc>
    00995     inline bool
    00996     operator<=(const _CharT* __lhs,
    00997            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    00998   { return __rhs.compare(__lhs) >= 0; }
    00999
    01000   // operator >=
    01001   template<typename _CharT, typename _Traits, typename _Alloc>
    01002     inline bool
    01003     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    01004            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    01005     { return __lhs.compare(__rhs) >= 0; }
    01006
    01007   template<typename _CharT, typename _Traits, typename _Alloc>
    01008     inline bool
    01009     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    01010            const _CharT* __rhs)
    01011     { return __lhs.compare(__rhs) >= 0; }
    01012
    01013   template<typename _CharT, typename _Traits, typename _Alloc>
    01014     inline bool
    01015     operator>=(const _CharT* __lhs,
    01016          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    01017     { return __rhs.compare(__lhs) <= 0; }
    01018
    01019
    01020   template<typename _CharT, typename _Traits, typename _Alloc>
    01021     inline void
    01022     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
    01023      basic_string<_CharT, _Traits, _Alloc>& __rhs)
    01024     { __lhs.swap(__rhs); }
    01025
    01026   template<typename _CharT, typename _Traits, typename _Alloc>
    01027     basic_istream<_CharT, _Traits>&
    01028     operator>>(basic_istream<_CharT, _Traits>& __is,
    01029            basic_string<_CharT, _Traits, _Alloc>& __str);
    01030
    01031   template<typename _CharT, typename _Traits, typename _Alloc>
    01032     basic_ostream<_CharT, _Traits>&
    01033     operator<<(basic_ostream<_CharT, _Traits>& __os,
    01034            const basic_string<_CharT, _Traits, _Alloc>& __str);
    01035
    01036   template<typename _CharT, typename _Traits, typename _Alloc>
    01037     basic_istream<_CharT,_Traits>&
    01038     getline(basic_istream<_CharT, _Traits>& __is,
    01039         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
    01040
    01041   template<typename _CharT, typename _Traits, typename _Alloc>
    01042     inline basic_istream<_CharT,_Traits>&
    01043     getline(basic_istream<_CharT, _Traits>& __is,
    01044         basic_string<_CharT, _Traits, _Alloc>& __str);
    01045 } // namespace std
    01046
    01047 #endif /* _CPP_BITS_STRING_H */