Copyright (C) 2000-2012 |
Whole document tree basic_string.hGo 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 1.2.15 |