Whole document tree
    

Whole document tree

basic_string.h Source File
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[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
00235 
00236       _CharT* 
00237       _M_data() const 
00238       { return  _M_dataplus._M_p; }
00239 
00240       _CharT* 
00241       _M_data(_CharT* __p) 
00242       { return (_M_dataplus._M_p = __p); }
00243 
00244       _Rep* 
00245       _M_rep() const
00246       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
00247 
00248       // For the internal use we have functions similar to `begin'/`end'
00249       // but they do not call _M_leak.
00250       iterator 
00251       _M_ibegin() const { return iterator(_M_data()); }
00252 
00253       iterator 
00254       _M_iend() const { return iterator(_M_data() + this->size()); }
00255 
00256       void 
00257       _M_leak()    // for use in begin() & non-const op[]
00258       { 
00259     if (!_M_rep()->_M_is_leaked()) 
00260       _M_leak_hard(); 
00261       }
00262 
00263       iterator 
00264       _M_check(size_type __pos) const
00265       { 
00266     if (__pos > this->size())
00267       __throw_out_of_range("basic_string::_M_check"); 
00268     return _M_ibegin() + __pos; 
00269       }
00270 
00271       // NB: _M_fold doesn't check for a bad __pos1 value.
00272       iterator 
00273       _M_fold(size_type __pos, size_type __off) const
00274       { 
00275     bool __testoff =  __off < this->size() - __pos;
00276     size_type __newoff = __testoff ? __off : this->size() - __pos;
00277     return (_M_ibegin() + __pos + __newoff);
00278       }
00279 
00280       // _S_copy_chars is a separate template to permit specialization
00281       // to optimize for the common case of pointers as iterators.
00282       template<class _Iterator>
00283         static void
00284         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00285         { 
00286       for (; __k1 != __k2; ++__k1, ++__p) 
00287         traits_type::assign(*__p, *__k1); //these types are off
00288     }
00289 
00290       static void
00291       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
00292       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00293 
00294       static void
00295       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
00296       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00297  
00298       static void
00299       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00300       { traits_type::copy(__p, __k1, __k2 - __k1); }
00301 
00302       static void
00303       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00304       { traits_type::copy(__p, __k1, __k2 - __k1); }
00305 
00306       void 
00307       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
00308 
00309       void 
00310       _M_leak_hard();
00311 
00312       static _Rep& 
00313       _S_empty_rep()
00314       { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
00315 
00316     public:
00317       // Construct/copy/destroy:
00318       // NB: We overload ctors in some cases instead of using default
00319       // arguments, per 17.4.4.4 para. 2 item 2.
00320 
00321       inline 
00322       basic_string();
00323 
00324       explicit 
00325       basic_string(const _Alloc& __a);
00326 
00327       // NB: per LWG issue 42, semantics different from IS:
00328       basic_string(const basic_string& __str);
00329       basic_string(const basic_string& __str, size_type __pos,
00330            size_type __n = npos);
00331       basic_string(const basic_string& __str, size_type __pos,
00332            size_type __n, const _Alloc& __a);
00333 
00334       basic_string(const _CharT* __s, size_type __n,
00335            const _Alloc& __a = _Alloc());
00336       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
00337       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
00338 
00339       template<class _InputIterator>
00340         basic_string(_InputIterator __begin, _InputIterator __end,
00341              const _Alloc& __a = _Alloc());
00342 
00343       ~basic_string() 
00344       { _M_rep()->_M_dispose(this->get_allocator()); }
00345 
00346       basic_string& 
00347       operator=(const basic_string& __str) { return this->assign(__str); }
00348 
00349       basic_string& 
00350       operator=(const _CharT* __s) { return this->assign(__s); }
00351 
00352       basic_string& 
00353       operator=(_CharT __c) { return this->assign(1, __c); }
00354 
00355       // Iterators:
00356       iterator 
00357       begin() 
00358       { 
00359     _M_leak(); 
00360     return iterator(_M_data());
00361       }
00362 
00363       const_iterator 
00364       begin() const 
00365       { return const_iterator(_M_data()); }
00366 
00367       iterator 
00368       end()
00369       {
00370          _M_leak();
00371      return iterator(_M_data() + this->size());
00372       }
00373 
00374       const_iterator 
00375       end() const
00376       { return const_iterator(_M_data() + this->size()); }
00377 
00378       reverse_iterator 
00379       rbegin() 
00380       { return reverse_iterator(this->end()); }
00381 
00382       const_reverse_iterator 
00383       rbegin() const 
00384       { return const_reverse_iterator(this->end()); }
00385 
00386       reverse_iterator 
00387       rend() 
00388       { return reverse_iterator(this->begin()); }
00389 
00390       const_reverse_iterator 
00391       rend() const 
00392       { return const_reverse_iterator(this->begin()); }
00393 
00394     public:
00395       // Capacity:
00396       size_type 
00397       size() const { return _M_rep()->_M_length; }
00398 
00399       size_type 
00400       length() const { return _M_rep()->_M_length; }
00401 
00402       size_type 
00403       max_size() const { return _Rep::_S_max_size; }
00404 
00405       void 
00406       resize(size_type __n, _CharT __c);
00407 
00408       void 
00409       resize(size_type __n) { this->resize(__n, _CharT()); }
00410 
00411       size_type 
00412       capacity() const { return _M_rep()->_M_capacity; }
00413 
00414       void 
00415       reserve(size_type __res_arg = 0);
00416 
00417       void 
00418       clear() { _M_mutate(0, this->size(), 0); }
00419 
00420       bool 
00421       empty() const { return this->size() == 0; }
00422 
00423       // Element access:
00424       const_reference 
00425       operator[] (size_type __pos) const 
00426       { return _M_data()[__pos]; }
00427 
00428       reference 
00429       operator[](size_type __pos) 
00430       { 
00431     _M_leak(); 
00432     return _M_data()[__pos]; 
00433       }
00434 
00435       const_reference 
00436       at(size_type __n) const
00437       {
00438     if (__n >= this->size())
00439       __throw_out_of_range("basic_string::at");
00440     return _M_data()[__n]; 
00441       }
00442 
00443       reference 
00444       at(size_type __n)
00445       {
00446     if (__n >= size())
00447       __throw_out_of_range("basic_string::at");
00448     _M_leak(); 
00449     return _M_data()[__n]; 
00450       }
00451 
00452       // Modifiers:
00453       basic_string& 
00454       operator+=(const basic_string& __str) { return this->append(__str); }
00455 
00456       basic_string& 
00457       operator+=(const _CharT* __s) { return this->append(__s); }
00458 
00459       basic_string& 
00460       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
00461 
00462       basic_string& 
00463       append(const basic_string& __str);
00464 
00465       basic_string& 
00466       append(const basic_string& __str, size_type __pos, size_type __n);
00467 
00468       basic_string& 
00469       append(const _CharT* __s, size_type __n);
00470 
00471       basic_string& 
00472       append(const _CharT* __s)
00473       { return this->append(__s, traits_type::length(__s)); }
00474 
00475       basic_string& 
00476       append(size_type __n, _CharT __c);
00477 
00478       template<class _InputIterator>
00479         basic_string& 
00480         append(_InputIterator __first, _InputIterator __last)
00481         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
00482 
00483       void 
00484       push_back(_CharT __c)
00485       { this->replace(_M_iend(), _M_iend(), 1, __c); }
00486 
00487       basic_string& 
00488       assign(const basic_string& __str);
00489 
00490       basic_string& 
00491       assign(const basic_string& __str, size_type __pos, size_type __n)
00492       { 
00493     return this->assign(__str._M_check(__pos), __str._M_fold(__pos, __n)); 
00494       }
00495 
00496       basic_string& 
00497       assign(const _CharT* __s, size_type __n)
00498       { return this->assign(__s, __s + __n); }
00499 
00500       basic_string& 
00501       assign(const _CharT* __s)
00502       { return this->assign(__s, __s + traits_type::length(__s)); }
00503 
00504       basic_string& 
00505       assign(size_type __n, _CharT __c)
00506       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
00507 
00508       template<class _InputIterator>
00509         basic_string& 
00510         assign(_InputIterator __first, _InputIterator __last)
00511         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
00512 
00513       void 
00514       insert(iterator __p, size_type __n, _CharT __c)
00515       { this->replace(__p, __p, __n, __c);  }
00516 
00517       template<class _InputIterator>
00518         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
00519         { this->replace(__p, __p, __beg, __end); }
00520 
00521       basic_string& 
00522       insert(size_type __pos1, const basic_string& __str)
00523       { 
00524     iterator __p = _M_check(__pos1);
00525     this->replace(__p, __p, __str._M_ibegin(), __str._M_iend());
00526         return *this; 
00527       }
00528 
00529       basic_string& 
00530       insert(size_type __pos1, const basic_string& __str,
00531          size_type __pos2, size_type __n)
00532       { 
00533     iterator __p = _M_check(__pos1);
00534     this->replace(__p, __p, __str._M_check(__pos2), 
00535               __str._M_fold(__pos2, __n));
00536         return *this; 
00537       }
00538 
00539       basic_string& 
00540       insert(size_type __pos, const _CharT* __s, size_type __n)
00541       { 
00542     iterator __p = _M_check(__pos);
00543     this->replace(__p, __p, __s, __s + __n);
00544         return *this; 
00545       }
00546 
00547       basic_string&  
00548       insert(size_type __pos, const _CharT* __s)
00549       { return this->insert(__pos, __s, traits_type::length(__s)); }
00550 
00551       basic_string& 
00552       insert(size_type __pos, size_type __n, _CharT __c)
00553       { 
00554     this->insert(_M_check(__pos), __n, __c); 
00555     return *this; 
00556       }
00557 
00558       iterator 
00559       insert(iterator __p, _CharT __c = _CharT())
00560       {
00561     size_type __pos = __p - _M_ibegin();
00562     this->insert(_M_check(__pos), size_type(1), __c);
00563     _M_rep()->_M_set_leaked(); 
00564     return this->_M_ibegin() + __pos; 
00565       }
00566 
00567       basic_string& 
00568       erase(size_type __pos = 0, size_type __n = npos)
00569       { 
00570     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
00571                  _M_data(), _M_data()); 
00572       }
00573 
00574       iterator 
00575       erase(iterator __position)
00576       {
00577     size_type __i = __position - _M_ibegin();
00578         this->replace(__position, __position + 1, _M_data(), _M_data());
00579     _M_rep()->_M_set_leaked(); 
00580     return _M_ibegin() + __i;
00581       }
00582 
00583       iterator 
00584       erase(iterator __first, iterator __last)
00585       {
00586         size_type __i = __first - _M_ibegin();
00587     this->replace(__first, __last, _M_data(), _M_data());
00588     _M_rep()->_M_set_leaked();
00589        return _M_ibegin() + __i;
00590       }
00591 
00592       basic_string& 
00593       replace(size_type __pos, size_type __n, const basic_string& __str)
00594       { 
00595     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
00596                   __str.begin(), __str.end()); 
00597       }
00598 
00599       basic_string& 
00600       replace(size_type __pos1, size_type __n1, const basic_string& __str,
00601           size_type __pos2, size_type __n2);
00602 
00603       basic_string& 
00604       replace(size_type __pos, size_type __n1, const _CharT* __s,
00605           size_type __n2)
00606       { 
00607     return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
00608                  __s, __s + __n2); 
00609       }
00610 
00611       basic_string& 
00612       replace(size_type __pos, size_type __n1, const _CharT* __s)
00613       { 
00614     return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
00615                  __s, __s + traits_type::length(__s)); 
00616       }
00617 
00618       basic_string& 
00619       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00620       { 
00621     return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c);
00622       }
00623 
00624       basic_string& 
00625       replace(iterator __i1, iterator __i2, const basic_string& __str)
00626       { return this->replace(__i1, __i2, __str.begin(), __str.end()); }
00627 
00628       basic_string& 
00629       replace(iterator __i1, iterator __i2,
00630                            const _CharT* __s, size_type __n)
00631       { return this->replace(__i1, __i2, __s, __s + __n); }
00632 
00633       basic_string& 
00634       replace(iterator __i1, iterator __i2, const _CharT* __s)
00635       { return this->replace(__i1, __i2, __s, 
00636                  __s + traits_type::length(__s)); }
00637 
00638       basic_string& 
00639       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
00640 
00641       template<class _InputIterator>
00642         basic_string& 
00643         replace(iterator __i1, iterator __i2,
00644         _InputIterator __k1, _InputIterator __k2)
00645         { return _M_replace(__i1, __i2, __k1, __k2,
00646          typename iterator_traits<_InputIterator>::iterator_category()); }
00647 
00648     private:
00649       template<class _InputIterator>
00650         basic_string& 
00651         _M_replace(iterator __i1, iterator __i2, _InputIterator __k1, 
00652            _InputIterator __k2, input_iterator_tag);
00653 
00654       template<class _FwdIterator>
00655         basic_string& 
00656         _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1, 
00657            _FwdIterator __k2, forward_iterator_tag);
00658 
00659       // _S_construct_aux is used to implement the 21.3.1 para 15 which
00660       // requires special behaviour if _InIter is an integral type
00661       template<class _InIter>
00662         static _CharT*
00663         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
00664              __false_type)
00665     {
00666           typedef typename iterator_traits<_InIter>::iterator_category _Tag;
00667           return _S_construct(__beg, __end, __a, _Tag());
00668     }
00669  
00670       template<class _InIter>
00671         static _CharT*
00672         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
00673              __true_type)
00674     {
00675       return _S_construct(static_cast<size_type>(__beg),
00676                   static_cast<value_type>(__end), __a);
00677     }
00678  
00679       template<class _InIter>
00680         static _CharT*
00681         _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
00682     {
00683       typedef typename _Is_integer<_InIter>::_Integral _Integral;
00684       return _S_construct_aux(__beg, __end, __a, _Integral());
00685         }
00686 
00687       // For Input Iterators, used in istreambuf_iterators, etc.
00688       template<class _InIter>
00689         static _CharT*
00690          _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
00691               input_iterator_tag);
00692       
00693       // For forward_iterators up to random_access_iterators, used for
00694       // string::iterator, _CharT*, etc.
00695       template<class _FwdIter>
00696         static _CharT*
00697         _S_construct(_FwdIter __end, _FwdIter __beg, const _Alloc& __a,
00698              forward_iterator_tag);
00699 
00700       static _CharT* 
00701       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
00702 
00703     public:
00704 
00705       size_type 
00706       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
00707 
00708       void 
00709       swap(basic_string<_CharT, _Traits, _Alloc>& __s);
00710 
00711       // String operations:
00712       const _CharT* 
00713       c_str() const
00714       {
00715     // MT: This assumes concurrent writes are OK.
00716     size_type __n = this->size();
00717     traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
00718         return _M_data();
00719       }
00720 
00721       const _CharT* 
00722       data() const { return _M_data(); }
00723 
00724       allocator_type 
00725       get_allocator() const { return _M_dataplus; }
00726 
00727       size_type 
00728       find(const _CharT* __s, size_type __pos, size_type __n) const;
00729 
00730       size_type 
00731       find(const basic_string& __str, size_type __pos = 0) const
00732       { return this->find(__str.data(), __pos, __str.size()); }
00733 
00734       size_type 
00735       find(const _CharT* __s, size_type __pos = 0) const
00736       { return this->find(__s, __pos, traits_type::length(__s)); }
00737 
00738       size_type 
00739       find(_CharT __c, size_type __pos = 0) const;
00740 
00741       size_type 
00742       rfind(const basic_string& __str, size_type __pos = npos) const
00743       { return this->rfind(__str.data(), __pos, __str.size()); }
00744 
00745       size_type 
00746       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
00747 
00748       size_type 
00749       rfind(const _CharT* __s, size_type __pos = npos) const
00750       { return this->rfind(__s, __pos, traits_type::length(__s)); }
00751 
00752       size_type 
00753       rfind(_CharT __c, size_type __pos = npos) const;
00754 
00755       size_type 
00756       find_first_of(const basic_string& __str, size_type __pos = 0) const
00757       { return this->find_first_of(__str.data(), __pos, __str.size()); }
00758 
00759       size_type 
00760       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
00761 
00762       size_type 
00763       find_first_of(const _CharT* __s, size_type __pos = 0) const
00764       { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
00765 
00766       size_type 
00767       find_first_of(_CharT __c, size_type __pos = 0) const
00768       { return this->find(__c, __pos); }
00769 
00770       size_type 
00771       find_last_of(const basic_string& __str, size_type __pos = npos) const
00772       { return this->find_last_of(__str.data(), __pos, __str.size()); }
00773 
00774       size_type 
00775       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
00776 
00777       size_type 
00778       find_last_of(const _CharT* __s, size_type __pos = npos) const
00779       { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
00780 
00781       size_type 
00782       find_last_of(_CharT __c, size_type __pos = npos) const
00783       { return this->rfind(__c, __pos); }
00784 
00785       size_type 
00786       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00787       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
00788 
00789       size_type 
00790       find_first_not_of(const _CharT* __s, size_type __pos, 
00791             size_type __n) const;
00792 
00793       size_type 
00794       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00795       { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
00796 
00797       size_type 
00798       find_first_not_of(_CharT __c, size_type __pos = 0) const;
00799 
00800       size_type 
00801       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
00802       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
00803 
00804       size_type 
00805       find_last_not_of(const _CharT* __s, size_type __pos, 
00806                size_type __n) const;
00807       size_type 
00808       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
00809       { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
00810 
00811       size_type 
00812       find_last_not_of(_CharT __c, size_type __pos = npos) const;
00813 
00814       basic_string 
00815       substr(size_type __pos = 0, size_type __n = npos) const
00816       { 
00817     if (__pos > this->size())
00818       __throw_out_of_range("basic_string::substr");
00819     return basic_string(*this, __pos, __n); 
00820       }
00821 
00822       int 
00823       compare(const basic_string& __str) const
00824       {
00825     size_type __size = this->size();
00826     size_type __osize = __str.size();
00827     size_type __len = min(__size, __osize);
00828       
00829     int __r = traits_type::compare(_M_data(), __str.data(), __len);
00830     if (!__r)
00831       __r =  __size - __osize;
00832     return __r;
00833       }
00834 
00835       int 
00836       compare(size_type __pos, size_type __n, const basic_string& __str) const;
00837 
00838       int 
00839       compare(size_type __pos1, size_type __n1, const basic_string& __str,
00840           size_type __pos2, size_type __n2) const;
00841 
00842       int 
00843       compare(const _CharT* __s) const;
00844 
00845 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00846 // 5. String::compare specification questionable
00847       int 
00848       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
00849 
00850       int 
00851       compare(size_type __pos, size_type __n1, const _CharT* __s, 
00852           size_type __n2) const;
00853 #endif
00854   };
00855 
00856 
00857   template<typename _CharT, typename _Traits, typename _Alloc>
00858     inline basic_string<_CharT, _Traits, _Alloc>::
00859     basic_string()
00860     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
00861 
00862   // operator+
00863   template<typename _CharT, typename _Traits, typename _Alloc>
00864     basic_string<_CharT, _Traits, _Alloc>
00865     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00866           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00867     {
00868       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00869       __str.append(__rhs);
00870       return __str;
00871     }
00872 
00873   template<typename _CharT, typename _Traits, typename _Alloc>
00874     basic_string<_CharT,_Traits,_Alloc>
00875     operator+(const _CharT* __lhs,
00876           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00877 
00878   template<typename _CharT, typename _Traits, typename _Alloc>
00879     basic_string<_CharT,_Traits,_Alloc>
00880     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
00881 
00882   template<typename _CharT, typename _Traits, typename _Alloc>
00883     inline basic_string<_CharT, _Traits, _Alloc>
00884     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00885          const _CharT* __rhs)
00886     {
00887       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
00888       __str.append(__rhs);
00889       return __str;
00890     }
00891 
00892   template<typename _CharT, typename _Traits, typename _Alloc>
00893     inline basic_string<_CharT, _Traits, _Alloc>
00894     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
00895     {
00896       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
00897       typedef typename __string_type::size_type     __size_type;
00898       __string_type __str(__lhs);
00899       __str.append(__size_type(1), __rhs);
00900       return __str;
00901     }
00902 
00903   // operator ==
00904   template<typename _CharT, typename _Traits, typename _Alloc>
00905     inline bool
00906     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00907            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00908     { return __lhs.compare(__rhs) == 0; }
00909 
00910   template<typename _CharT, typename _Traits, typename _Alloc>
00911     inline bool
00912     operator==(const _CharT* __lhs,
00913            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00914     { return __rhs.compare(__lhs) == 0; }
00915 
00916   template<typename _CharT, typename _Traits, typename _Alloc>
00917     inline bool
00918     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00919            const _CharT* __rhs)
00920     { return __lhs.compare(__rhs) == 0; }
00921 
00922   // operator !=
00923   template<typename _CharT, typename _Traits, typename _Alloc>
00924     inline bool
00925     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00926            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00927     { return __rhs.compare(__lhs) != 0; }
00928 
00929   template<typename _CharT, typename _Traits, typename _Alloc>
00930     inline bool
00931     operator!=(const _CharT* __lhs,
00932            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00933     { return __rhs.compare(__lhs) != 0; }
00934 
00935   template<typename _CharT, typename _Traits, typename _Alloc>
00936     inline bool
00937     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00938            const _CharT* __rhs)
00939     { return __lhs.compare(__rhs) != 0; }
00940 
00941   // operator <
00942   template<typename _CharT, typename _Traits, typename _Alloc>
00943     inline bool
00944     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00945           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00946     { return __lhs.compare(__rhs) < 0; }
00947 
00948   template<typename _CharT, typename _Traits, typename _Alloc>
00949     inline bool
00950     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00951           const _CharT* __rhs)
00952     { return __lhs.compare(__rhs) < 0; }
00953 
00954   template<typename _CharT, typename _Traits, typename _Alloc>
00955     inline bool
00956     operator<(const _CharT* __lhs,
00957           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00958     { return __rhs.compare(__lhs) > 0; }
00959 
00960   // operator >
00961   template<typename _CharT, typename _Traits, typename _Alloc>
00962     inline bool
00963     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00964           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00965     { return __lhs.compare(__rhs) > 0; }
00966 
00967   template<typename _CharT, typename _Traits, typename _Alloc>
00968     inline bool
00969     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00970           const _CharT* __rhs)
00971     { return __lhs.compare(__rhs) > 0; }
00972 
00973   template<typename _CharT, typename _Traits, typename _Alloc>
00974     inline bool
00975     operator>(const _CharT* __lhs,
00976           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00977     { return __rhs.compare(__lhs) < 0; }
00978 
00979   // operator <=
00980   template<typename _CharT, typename _Traits, typename _Alloc>
00981     inline bool
00982     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00983            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00984     { return __lhs.compare(__rhs) <= 0; }
00985 
00986   template<typename _CharT, typename _Traits, typename _Alloc>
00987     inline bool
00988     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
00989            const _CharT* __rhs)
00990     { return __lhs.compare(__rhs) <= 0; }
00991 
00992   template<typename _CharT, typename _Traits, typename _Alloc>
00993     inline bool
00994     operator<=(const _CharT* __lhs,
00995            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00996   { return __rhs.compare(__lhs) >= 0; }
00997 
00998   // operator >=
00999   template<typename _CharT, typename _Traits, typename _Alloc>
01000     inline bool
01001     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01002            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01003     { return __lhs.compare(__rhs) >= 0; }
01004 
01005   template<typename _CharT, typename _Traits, typename _Alloc>
01006     inline bool
01007     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
01008            const _CharT* __rhs)
01009     { return __lhs.compare(__rhs) >= 0; }
01010 
01011   template<typename _CharT, typename _Traits, typename _Alloc>
01012     inline bool
01013     operator>=(const _CharT* __lhs,
01014          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
01015     { return __rhs.compare(__lhs) <= 0; }
01016 
01017 
01018   template<typename _CharT, typename _Traits, typename _Alloc>
01019     inline void
01020     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
01021      basic_string<_CharT, _Traits, _Alloc>& __rhs)
01022     { __lhs.swap(__rhs); }
01023 
01024   template<typename _CharT, typename _Traits, typename _Alloc>
01025     basic_istream<_CharT, _Traits>&
01026     operator>>(basic_istream<_CharT, _Traits>& __is,
01027            basic_string<_CharT, _Traits, _Alloc>& __str);
01028 
01029   template<typename _CharT, typename _Traits, typename _Alloc>
01030     basic_ostream<_CharT, _Traits>&
01031     operator<<(basic_ostream<_CharT, _Traits>& __os,
01032            const basic_string<_CharT, _Traits, _Alloc>& __str);
01033 
01034   template<typename _CharT, typename _Traits, typename _Alloc>
01035     basic_istream<_CharT,_Traits>&
01036     getline(basic_istream<_CharT, _Traits>& __is,
01037         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
01038 
01039   template<typename _CharT, typename _Traits, typename _Alloc>
01040     inline basic_istream<_CharT,_Traits>&
01041     getline(basic_istream<_CharT, _Traits>& __is,
01042         basic_string<_CharT, _Traits, _Alloc>& __str);
01043 } // namespace std
01044 
01045 #endif /* _CPP_BITS_STRING_H */

Generated on Mon Apr 8 03:11:22 2002 for libstdc++-v3 Source by doxygen1.2.15