Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

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 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 //
00031 // ISO C++ 14882: 21 Strings library
00032 //
00033 
00034 #ifndef _CPP_BITS_STRING_H
00035 #define _CPP_BITS_STRING_H  1
00036 
00037 #pragma GCC system_header
00038 
00039 #include <bits/atomicity.h>
00040 
00041 namespace std
00042 {
00043 
00044   // Documentation?  What's that? 
00045   // Nathan Myers <ncm@cantrip.org>.
00046   //
00047   // A string looks like this:
00048   //
00049   //                                [_Rep]
00050   //                                _M_length
00051   //  [basic_string<char_type>]     _M_capacity
00052   //  _M_dataplus                   _M_state
00053   //  _M_p ---------------->        unnamed array of char_type
00054   
00055   // Where the _M_p points to the first character in the string, and
00056   // you cast it to a pointer-to-_Rep and subtract 1 to get a
00057   // pointer to the header.
00058   
00059   // This approach has the enormous advantage that a string object
00060   // requires only one allocation.  All the ugliness is confined
00061   // within a single pair of inline functions, which each compile to
00062   // a single "add" instruction: _Rep::_M_data(), and
00063   // string::_M_rep(); and the allocation function which gets a
00064   // block of raw bytes and with room enough and constructs a _Rep
00065   // object at the front.
00066   
00067   // The reason you want _M_data pointing to the character array and
00068   // not the _Rep is so that the debugger can see the string
00069   // contents. (Probably we should add a non-inline member to get
00070   // the _Rep for the debugger to use, so users can check the actual
00071   // string length.)
00072   
00073   // Note that the _Rep object is a POD so that you can have a
00074   // static "empty string" _Rep object already "constructed" before
00075   // static constructors have run.  The reference-count encoding is
00076   // chosen so that a 0 indicates one reference, so you never try to
00077   // destroy the empty-string _Rep object.
00078   
00079   // All but the last paragraph is considered pretty conventional
00080   // for a C++ string implementation.
00081   
00082   // 21.3  Template class basic_string
00083   template<typename _CharT, typename _Traits, typename _Alloc>
00084     class basic_string
00085     {
00086       // Types:
00087     public:
00088       typedef _Traits                       traits_type;
00089       typedef typename _Traits::char_type           value_type;
00090       typedef _Alloc                        allocator_type;
00091       typedef typename _Alloc::size_type            size_type;
00092       typedef typename _Alloc::difference_type          difference_type;
00093       typedef typename _Alloc::reference            reference;
00094       typedef typename _Alloc::const_reference          const_reference;
00095       typedef typename _Alloc::pointer              pointer;
00096       typedef typename _Alloc::const_pointer            const_pointer;
00097       typedef __normal_iterator<pointer, basic_string>      iterator;
00098       typedef __normal_iterator<const_pointer, basic_string> const_iterator;
00099       typedef reverse_iterator<const_iterator>  const_reverse_iterator;
00100       typedef reverse_iterator<iterator>            reverse_iterator;
00101     
00102     private:
00103       // _Rep: string representation
00104       //   Invariants:
00105       //   1. String really contains _M_length + 1 characters; last is set
00106       //      to 0 only on call to c_str().  We avoid instantiating
00107       //      _CharT() where the interface does not require it.
00108       //   2. _M_capacity >= _M_length
00109       //      Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
00110       //   3. _M_references has three states:
00111       //      -1: leaked, one reference, no ref-copies allowed, non-const.
00112       //       0: one reference, non-const.
00113       //     n>0: n + 1 references, operations require a lock, const.
00114       //   4. All fields==0 is an empty string, given the extra storage
00115       //      beyond-the-end for a null terminator; thus, the shared
00116       //      empty string representation needs no constructor.
00117 
00118       struct _Rep
00119       {
00120     // Types:
00121     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
00122 
00123     // (Public) Data members: 
00124 
00125     // The maximum number of individual char_type elements of an
00126     // individual string is determined by _S_max_size. This is the
00127     // value that will be returned by max_size().  (Whereas npos
00128     // is the maximum number of bytes the allocator can allocate.)
00129     // If one was to divvy up the theoretical largest size string,
00130     // with a terminating character and m _CharT elements, it'd
00131     // look like this: 
00132     // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
00133     // Solving for m:
00134     // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 
00135     // In addition, this implementation quarters this ammount.
00136     static const size_type  _S_max_size;
00137     static const _CharT     _S_terminal;
00138 
00139     size_type       _M_length;
00140     size_type       _M_capacity;
00141     _Atomic_word        _M_references;
00142 
00143         bool
00144     _M_is_leaked() const
00145         { return _M_references < 0; }
00146 
00147         bool
00148     _M_is_shared() const
00149         { return _M_references > 0; }
00150 
00151         void
00152     _M_set_leaked() 
00153         { _M_references = -1; }
00154 
00155         void
00156     _M_set_sharable() 
00157     { _M_references = 0; }
00158 
00159     _CharT* 
00160     _M_refdata() throw()
00161     { return reinterpret_cast<_CharT*> (this + 1); }
00162 
00163     _CharT& 
00164     operator[](size_t __s) throw()
00165     { return _M_refdata() [__s]; }
00166 
00167     _CharT* 
00168     _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
00169     { return (!_M_is_leaked() && __alloc1 == __alloc2) ?
00170         _M_refcopy() : _M_clone(__alloc1);  }
00171 
00172     // Create & Destroy
00173     static _Rep* 
00174     _S_create(size_t, const _Alloc&);
00175 
00176     void 
00177     _M_dispose(const _Alloc& __a)
00178     { 
00179       if (__exchange_and_add(&_M_references, -1) <= 0)  
00180         _M_destroy(__a); 
00181     }  // XXX MT
00182 
00183     void 
00184     _M_destroy(const _Alloc&) throw();
00185 
00186     _CharT* 
00187     _M_refcopy() throw()
00188     { 
00189       __atomic_add(&_M_references, 1); 
00190       return _M_refdata(); 
00191     }  // XXX MT
00192 
00193     _CharT* 
00194     _M_clone(const _Alloc&, size_type __res = 0);
00195 
00196 #if _GLIBCPP_ALLOC_CONTROL
00197     // These function pointers allow you to modify the allocation
00198     // policy used by the string classes.  By default they expand by
00199     // powers of two, but this may be excessive for space-critical
00200     // applications.
00201     
00202     // Returns true if ALLOCATED is too much larger than LENGTH
00203     static bool (*_S_excess_slop) (size_t __length, size_t __allocated);
00204 
00205     inline static bool 
00206     __default_excess(size_t, size_t);
00207 #else
00208     inline static bool 
00209     _S_excess_slop(size_t, size_t);
00210 #endif
00211       };
00212 
00213       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
00214       struct _Alloc_hider : _Alloc
00215       {
00216     _Alloc_hider(_CharT* __dat, const _Alloc& __a)
00217     : _Alloc(__a), _M_p(__dat) { }
00218 
00219     _CharT* _M_p; // The actual data.
00220       };
00221 
00222     public:
00223       // Data Members (public):
00224       // NB: This is an unsigned type, and thus represents the maximum
00225       // size that the allocator can hold.
00226       static const size_type    npos = static_cast<size_type>(-1);
00227 
00228     private:
00229       // Data Members (private):
00230       mutable _Alloc_hider  _M_dataplus;
00231 
00232       // The following storage is init'd to 0 by the linker, resulting
00233       // (carefully) in an empty string with one reference.
00234       static size_type _S_empty_rep_storage[
00235     (sizeof(_Rep) + sizeof(_CharT)
00236      + sizeof(size_type) - 1)/sizeof(size_type)]
00237       __attribute__ ((__aligned__ (16)));
00238 
00239       _CharT* 
00240       _M_data() const 
00241       { return  _M_dataplus._M_p; }
00242 
00243       _CharT* 
00244       _M_data(_CharT* __p) 
00245       { return (_M_dataplus._M_p = __p); }
00246 
00247       _Rep* 
00248       _M_rep() const
00249       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
00250 
00251       // For the internal use we have functions similar to `begin'/`end'
00252       // but they do not call _M_leak.
00253       iterator 
00254       _M_ibegin() const { return iterator(_M_data()); }
00255 
00256       iterator 
00257       _M_iend() const { return iterator(_M_data() + this->size()); }
00258 
00259       void 
00260       _M_leak()    // for use in begin() & non-const op[]
00261       { 
00262     if (!_M_rep()->_M_is_leaked()) 
00263       _M_leak_hard(); 
00264       }
00265 
00266       iterator 
00267       _M_check(size_type __pos) const
00268       { 
00269     if (__pos > this->size())
00270       __throw_out_of_range("basic_string::_M_check"); 
00271     return _M_ibegin() + __pos; 
00272       }
00273 
00274       // NB: _M_fold doesn't check for a bad __pos1 value.
00275       iterator 
00276       _M_fold(size_type __pos, size_type __off) const
00277       { 
00278     bool __testoff =  __off < this->size() - __pos;
00279     size_type __newoff = __testoff ? __off : this->size() - __pos;
00280     return (_M_ibegin() + __pos + __newoff);
00281       }
00282 
00283       // _S_copy_chars is a separate template to permit specialization
00284       // to optimize for the common case of pointers as iterators.
00285       template<class _Iterator>
00286         static void
00287         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00288         { 
00289       for (; __k1 != __k2; ++__k1, ++__p) 
00290         traits_type::assign(*__p, *__k1); //these types are off
00291     }
00292 
00293       static void
00294       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
00295       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00296 
00297       static void
00298       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
00299       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00300  
00301       static void
00302       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00303       { traits_type::copy(__p, __k1, __k2 - __k1); }
00304 
00305       static void
00306       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00307       { traits_type::copy(__p, __k1, __k2 - __k1); }
00308 
00309       void 
00310       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
00311 
00312       void 
00313       _M_leak_hard();
00314 
00315       static _Rep& 
00316       _S_empty_rep()
00317       { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
00318 
00319     public:
00320       // Construct/copy/destroy:
00321       // NB: We overload ctors in some cases instead of using default
00322       // arguments, per 17.4.4.4 para. 2 item 2.
00323 
00324       inline 
00325       basic_string();
00326 
00327       explicit 
00328       basic_string(const _Alloc& __a);
00329 
00330       // NB: per LWG issue 42, semantics different from IS:
00331       basic_string(const basic_string& __str);
00332       basic_string(const basic_string& __str, size_type __pos,
00333            size_type __n = npos);
00334       basic_string(const basic_string& __str, size_type __pos,
00335            size_type __n, const _Alloc& __a);
00336 
00337       basic_string(const _CharT* __s, size_type __n,
00338            const _Alloc& __a = _Alloc());
00339       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
00340       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
00341 
00342       template<class _InputIterator>
00343         basic_string(_InputIterator __begin, _InputIterator __end,
00344              const _Alloc& __a = _Alloc());
00345 
00346       ~basic_string() 
00347       { _M_rep()->_M_dispose(this->get_allocator()); }
00348 
00349       basic_string& 
00350       operator=(const basic_string& __str) { return this->assign(__str); }
00351 
00352       basic_string& 
00353       operator=(const _CharT* __s) { return this->assign(__s); }
00354 
00355       basic_string& 
00356       operator=(_CharT __c) { return this->assign(1, __c); }
00357 
00358       // Iterators:
00359       iterator 
00360       begin() 
00361       { 
00362     _M_leak(); 
00363     return iterator(_M_data());
00364       }
00365 
00366       const_iterator 
00367       begin() const 
00368       { return const_iterator(_M_data()); }
00369 
00370       iterator 
00371       end()
00372       {
00373          _M_leak();
00374      return iterator(_M_data() + this->size());
00375       }
00376 
00377       const_iterator 
00378       end() const
00379       { return const_iterator(_M_data() + this->size()); }
00380 
00381       reverse_iterator 
00382       rbegin() 
00383       { return reverse_iterator(this->end()); }
00384 
00385       const_reverse_iterator 
00386       rbegin() const 
00387       { return const_reverse_iterator(this->end()); }
00388 
00389       reverse_iterator 
00390       rend() 
00391       { return reverse_iterator(this->begin()); }
00392 
00393       const_reverse_iterator 
00394       rend() const 
00395       { return const_reverse_iterator(this->begin()); }
00396 
00397     public:
00398       // Capacity:
00399       size_type 
00400       size() const { return _M_rep()->_M_length; }
00401 
00402       size_type 
00403       length() const { return _M_rep()->_M_length; }
00404 
00405       size_type 
00406       max_size() const { return _Rep::_S_max_size; }
00407 
00408       void 
00409       resize(size_type __n, _CharT __c);
00410 
00411       void 
00412       resize(size_type __n) { this->resize(__n, _CharT()); }
00413 
00414       size_type 
00415       capacity() const { return _M_rep()->_M_capacity; }
00416 
00417       void 
00418       reserve(size_type __res_arg = 0);
00419 
00420       void 
00421       clear() { _M_mutate(0, this->size(), 0); }
00422 
00423       bool 
00424       empty() const { return this->size() == 0; }
00425 
00426       // Element access:
00427       const_reference 
00428       operator[] (size_type __pos) const 
00429       { return _M_data()[__pos]; }
00430 
00431       reference 
00432       operator[](size_type __pos) 
00433       { 
00434     _M_leak(); 
00435     return _M_data()[__pos]; 
00436       }
00437 
00438       const_reference 
00439       at(size_type __n) const
00440       {
00441     if (__n >= this->size())
00442       __throw_out_of_range("basic_string::at");
00443     return _M_data()[__n]; 
00444       }
00445 
00446       reference 
00447       at(size_type __n)
00448       {
00449     if (__n >= size())
00450       __throw_out_of_range("basic_string::at");
00451     _M_leak(); 
00452     return _M_data()[__n]; 
00453       }
00454 
00455       // Modifiers:
00456       basic_string& 
00457       operator+=(const basic_string& __str) { return this->append(__str); }
00458 
00459       basic_string& 
00460       operator+=(const _CharT* __s) { return this->append(__s); }
00461 
00462       basic_string& 
00463       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
00464 
00465       basic_string& 
00466       append(const basic_string& __str);
00467 
00468       basic_string& 
00469       append(const basic_string& __str, size_type __pos, size_type __n);
00470 
00471       basic_string& 
00472       append(const _CharT* __s, size_type __n);
00473 
00474       basic_string& 
00475       append(const _CharT* __s)
00476       { return this->append(__s, traits_type::length(__s)); }
00477 
00478       basic_string& 
00479       append(size_type __n, _CharT __c);
00480 
00481       template<class _InputIterator>
00482         basic_string& 
00483         append(_InputIterator __first, _InputIterator __last)
00484         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
00485 
00486       void 
00487       push_back(_CharT __c)
00488       { this->replace(_M_iend(), _M_iend(), 1, __c); }
00489 
00490       basic_string& 
00491       assign(const basic_string& __str);
00492 
00493       basic_string& 
00494       assign(const basic_string& __str, size_type __pos, size_type __n)
00495       { 
00496     return this->assign(__str._M_check(__pos), __str._M_fold(__pos, __n)); 
00497       }
00498 
00499       basic_string& 
00500       assign(const _CharT* __s, size_type __n)
00501       { return this->assign(__s, __s + __n); }
00502 
00503       basic_string& 
00504       assign(const _CharT* __s)
00505       { return this->assign(__s, __s + traits_type::length(__s)); }
00506 
00507       basic_string& 
00508       assign(size_type __n, _CharT __c)
00509       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
00510 
00511       template<class _InputIterator>
00512         basic_string& 
00513         assign(_InputIterator __first, _InputIterator __last)
00514         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
00515 
00516       void 
00517       insert(iterator __p, size_type __n, _CharT __c)
00518       { this->replace(__p, __p, __n, __c);  }
00519 
00520       template<class _InputIterator>
00521         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
00522         { this->replace(__p, __p, __beg, __end); }
00523 
00524       basic_string& 
00525       insert(size_type __pos1, const basic_string& __str)
00526       { 
00527     iterator __p = _M_check(__pos1);
00528     this->replace(__p, __p, __str._M_ibegin(), __str._M_iend());
00529         return *this; 
00530       }
00531 
00532       basic_string& 
00533       insert(size_type __pos1, const basic_string& __str,
00534          size_type __pos2, size_type __n)
00535       { 
00536     iterator __p = _M_check(__pos1);
00537     this->replace(__p, __p, __str._M_check(__pos2), 
00538               __str._M_fold(__pos2, __n));
00539         return *this; 
00540       }
00541 
00542       basic_string& 
00543       insert(size_type __pos, const _CharT* __s, size_type __n)
00544       { 
00545     iterator __p = _M_check(__pos);
00546     this->replace(__p, __p, __s, __s + __n);
00547         return *this; 
00548       }
00549 
00550       basic_string&  
00551       insert(size_type __pos, const _CharT* __s)
00552       { return this->insert(__pos, __s, traits_type::length(__s)); }
00553 
00554       basic_string& 
00555       insert(size_type __pos, size_type __n, _CharT __c)
00556       { 
00557     this->insert(_M_check(__pos), __n, __c); 
00558     return *this; 
00559       }
00560 
00561       iterator 
00562       insert(iterator __p, _CharT __c = _CharT())
00563       {
00564     size_type __pos = __p - _M_ibegin();
00565     this->insert(_M_check(__pos), size_type(1), __c);
00566     _M_rep()->_M_set_leaked(); 
00567     return this->_M_ibegin() + __pos; 
00568       }
00569 
00570       basic_string& 
00571       erase(size_type __pos = 0, size_type __n = npos)
00572       { 
00573     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
00574                  _M_data(), _M_data()); 
00575       }
00576 
00577       iterator 
00578       erase(iterator __position)
00579       {
00580     size_type __i = __position - _M_ibegin();
00581         this->replace(__position, __position + 1, _M_data(), _M_data());
00582     _M_rep()->_M_set_leaked(); 
00583     return _M_ibegin() + __i;
00584       }
00585 
00586       iterator 
00587       erase(iterator __first, iterator __last)
00588       {
00589         size_type __i = __first - _M_ibegin();
00590     this->replace(__first, __last, _M_data(), _M_data());
00591     _M_rep()->_M_set_leaked();
00592        return _M_ibegin() + __i;
00593       }
00594 
00595       basic_string& 
00596       replace(size_type __pos, size_type __n, const basic_string& __str)
00597       { 
00598     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
00599                   __str.begin(), __str.end()); 
00600       }
00601 
00602       basic_string& 
00603       replace(size_type __pos1, size_type __n1, const basic_string& __str,
00604           size_type __pos2, size_type __n2);
00605 
00606       basic_string& 
00607       replace(size_type __pos, size_type __n1, const _CharT* __s,
00608           size_type __n2)
00609       { 
00610     return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
00611                  __s, __s + __n2); 
00612       }
00613 
00614       basic_string& 
00615       replace(size_type __pos, size_type __n1, const _CharT* __s)
00616       { 
00617     return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
00618                  __s, __s + traits_type::length(__s)); 
00619       }
00620 
00621       basic_string& 
00622       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00623       { 
00624     return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c);
00625       }
00626 
00627       basic_string& 
00628       replace(iterator __i1, iterator __i2, const basic_string& __str)
00629       { return this->replace(__i1, __i2, __str.begin(), __str.end()); }
00630 
00631       basic_string& 
00632       replace(iterator __i1, iterator __i2,
00633                            const _CharT* __s, size_type __n)
00634       { return this->replace(__i1, __i2, __s, __s + __n); }
00635 
00636       basic_string& 
00637       replace(iterator __i1, iterator __i2, const _CharT* __s)
00638       { return this->replace(__i1, __i2, __s, 
00639                  __s + traits_type::length(__s)); }
00640 
00641       basic_string& 
00642       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
00643 
00644       template<class _InputIterator>
00645         basic_string& 
00646         replace(iterator __i1, iterator __i2,
00647         _InputIterator __k1, _InputIterator __k2)
00648         { return _M_replace(__i1, __i2, __k1, __k2,
00649          typename iterator_traits<_InputIterator>::iterator_category()); }
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 _FwdIterator>
00658         basic_string& 
00659         _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1, 
00660            _FwdIterator __k2, forward_iterator_tag);
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 __end, _FwdIter __beg, 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 = 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 #ifdef _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 #endif
00857   };
00858 
00859 
00860   template<typename _CharT, typename _Traits, typename _Alloc>
00861     inline basic_string<_CharT, _Traits, _Alloc>::
00862     basic_string()
00863     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
00864 
00865   // operator+
00866   template<typename _CharT, typename _Traits, typename _Alloc>
00867     basic_string<_CharT, _Traits, _Alloc>
00868     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00869           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00870     {
00871       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00872       __str.append(__rhs);
00873       return __str;
00874     }
00875 
00876   template<typename _CharT, typename _Traits, typename _Alloc>
00877     basic_string<_CharT,_Traits,_Alloc>
00878     operator+(const _CharT* __lhs,
00879           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00880 
00881   template<typename _CharT, typename _Traits, typename _Alloc>
00882     basic_string<_CharT,_Traits,_Alloc>
00883     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00884 
00885   template<typename _CharT, typename _Traits, typename _Alloc>
00886     inline basic_string<_CharT, _Traits, _Alloc>
00887     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00888          const _CharT* __rhs)
00889     {
00890       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00891       __str.append(__rhs);
00892       return __str;
00893     }
00894 
00895   template<typename _CharT, typename _Traits, typename _Alloc>
00896     inline basic_string<_CharT, _Traits, _Alloc>
00897     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
00898     {
00899       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
00900       typedef typename __string_type::size_type     __size_type;
00901       __string_type __str(__lhs);
00902       __str.append(__size_type(1), __rhs);
00903       return __str;
00904     }
00905 
00906   // operator ==
00907   template<typename _CharT, typename _Traits, typename _Alloc>
00908     inline bool
00909     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00910            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00911     { return __lhs.compare(__rhs) == 0; }
00912 
00913   template<typename _CharT, typename _Traits, typename _Alloc>
00914     inline bool
00915     operator==(const _CharT* __lhs,
00916            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00917     { return __rhs.compare(__lhs) == 0; }
00918 
00919   template<typename _CharT, typename _Traits, typename _Alloc>
00920     inline bool
00921     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00922            const _CharT* __rhs)
00923     { return __lhs.compare(__rhs) == 0; }
00924 
00925   // operator !=
00926   template<typename _CharT, typename _Traits, typename _Alloc>
00927     inline bool
00928     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00929            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00930     { return __rhs.compare(__lhs) != 0; }
00931 
00932   template<typename _CharT, typename _Traits, typename _Alloc>
00933     inline bool
00934     operator!=(const _CharT* __lhs,
00935            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00936     { return __rhs.compare(__lhs) != 0; }
00937 
00938   template<typename _CharT, typename _Traits, typename _Alloc>
00939     inline bool
00940     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00941            const _CharT* __rhs)
00942     { return __lhs.compare(__rhs) != 0; }
00943 
00944   // operator <
00945   template<typename _CharT, typename _Traits, typename _Alloc>
00946     inline bool
00947     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00948           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00949     { return __lhs.compare(__rhs) < 0; }
00950 
00951   template<typename _CharT, typename _Traits, typename _Alloc>
00952     inline bool
00953     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00954           const _CharT* __rhs)
00955     { return __lhs.compare(__rhs) < 0; }
00956 
00957   template<typename _CharT, typename _Traits, typename _Alloc>
00958     inline bool
00959     operator<(const _CharT* __lhs,
00960           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00961     { return __rhs.compare(__lhs) > 0; }
00962 
00963   // operator >
00964   template<typename _CharT, typename _Traits, typename _Alloc>
00965     inline bool
00966     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00967           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00968     { return __lhs.compare(__rhs) > 0; }
00969 
00970   template<typename _CharT, typename _Traits, typename _Alloc>
00971     inline bool
00972     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00973           const _CharT* __rhs)
00974     { return __lhs.compare(__rhs) > 0; }
00975 
00976   template<typename _CharT, typename _Traits, typename _Alloc>
00977     inline bool
00978     operator>(const _CharT* __lhs,
00979           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00980     { return __rhs.compare(__lhs) < 0; }
00981 
00982   // operator <=
00983   template<typename _CharT, typename _Traits, typename _Alloc>
00984     inline bool
00985     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00986            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00987     { return __lhs.compare(__rhs) <= 0; }
00988 
00989   template<typename _CharT, typename _Traits, typename _Alloc>
00990     inline bool
00991     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00992            const _CharT* __rhs)
00993     { return __lhs.compare(__rhs) <= 0; }
00994 
00995   template<typename _CharT, typename _Traits, typename _Alloc>
00996     inline bool
00997     operator<=(const _CharT* __lhs,
00998            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00999   { return __rhs.compare(__lhs) >= 0; }
01000 
01001   // operator >=
01002   template<typename _CharT, typename _Traits, typename _Alloc>
01003     inline bool
01004     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01005            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01006     { return __lhs.compare(__rhs) >= 0; }
01007 
01008   template<typename _CharT, typename _Traits, typename _Alloc>
01009     inline bool
01010     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01011            const _CharT* __rhs)
01012     { return __lhs.compare(__rhs) >= 0; }
01013 
01014   template<typename _CharT, typename _Traits, typename _Alloc>
01015     inline bool
01016     operator>=(const _CharT* __lhs,
01017          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01018     { return __rhs.compare(__lhs) <= 0; }
01019 
01020 
01021   template<typename _CharT, typename _Traits, typename _Alloc>
01022     inline void
01023     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
01024      basic_string<_CharT, _Traits, _Alloc>& __rhs)
01025     { __lhs.swap(__rhs); }
01026 
01027   template<typename _CharT, typename _Traits, typename _Alloc>
01028     basic_istream<_CharT, _Traits>&
01029     operator>>(basic_istream<_CharT, _Traits>& __is,
01030            basic_string<_CharT, _Traits, _Alloc>& __str);
01031 
01032   template<typename _CharT, typename _Traits, typename _Alloc>
01033     basic_ostream<_CharT, _Traits>&
01034     operator<<(basic_ostream<_CharT, _Traits>& __os,
01035            const basic_string<_CharT, _Traits, _Alloc>& __str);
01036 
01037   template<typename _CharT, typename _Traits, typename _Alloc>
01038     basic_istream<_CharT,_Traits>&
01039     getline(basic_istream<_CharT, _Traits>& __is,
01040         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
01041 
01042   template<typename _CharT, typename _Traits, typename _Alloc>
01043     inline basic_istream<_CharT,_Traits>&
01044     getline(basic_istream<_CharT, _Traits>& __is,
01045         basic_string<_CharT, _Traits, _Alloc>& __str);
01046 } // namespace std
01047 
01048 #endif /* _CPP_BITS_STRING_H */

Generated on Sat Apr 19 07:14:19 2003 for libstdc++-v3 Source by doxygen1.2.15