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 00035 /** @file basic_string.h 00036 * This is an internal header file, included by other library headers. 00037 * You should not attempt to use it directly. 00038 */ 00039 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 { 00049 /** 00050 * @class basic_string basic_string.h <string> 00051 * @brief Managing sequences of characters and character-like objects. 00052 * 00053 * @ingroup Containers 00054 * @ingroup Sequences 00055 * 00056 * Meets the requirements of a <a href="tables.html#65">container</a>, a 00057 * <a href="tables.html#66">reversible container</a>, and a 00058 * <a href="tables.html#67">sequence</a>. Of the 00059 * <a href="tables.html#68">optional sequence requirements</a>, only 00060 * @c push_back, @c at, and array access are supported. 00061 * 00062 * @doctodo 00063 * 00064 * 00065 * @if maint 00066 * Documentation? What's that? 00067 * Nathan Myers <ncm@cantrip.org>. 00068 * 00069 * A string looks like this: 00070 * 00071 * @code 00072 * [_Rep] 00073 * _M_length 00074 * [basic_string<char_type>] _M_capacity 00075 * _M_dataplus _M_state 00076 * _M_p ----------------> unnamed array of char_type 00077 * @endcode 00078 * 00079 * Where the _M_p points to the first character in the string, and 00080 * you cast it to a pointer-to-_Rep and subtract 1 to get a 00081 * pointer to the header. 00082 * 00083 * This approach has the enormous advantage that a string object 00084 * requires only one allocation. All the ugliness is confined 00085 * within a single pair of inline functions, which each compile to 00086 * a single "add" instruction: _Rep::_M_data(), and 00087 * string::_M_rep(); and the allocation function which gets a 00088 * block of raw bytes and with room enough and constructs a _Rep 00089 * object at the front. 00090 * 00091 * The reason you want _M_data pointing to the character array and 00092 * not the _Rep is so that the debugger can see the string 00093 * contents. (Probably we should add a non-inline member to get 00094 * the _Rep for the debugger to use, so users can check the actual 00095 * string length.) 00096 * 00097 * Note that the _Rep object is a POD so that you can have a 00098 * static "empty string" _Rep object already "constructed" before 00099 * static constructors have run. The reference-count encoding is 00100 * chosen so that a 0 indicates one reference, so you never try to 00101 * destroy the empty-string _Rep object. 00102 * 00103 * All but the last paragraph is considered pretty conventional 00104 * for a C++ string implementation. 00105 * @endif 00106 */ 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 */

Generated on Wed Aug 4 21:43:08 2004 for libstdc++-v3 Source by doxygen 1.3.8