libstdc++
|
00001 // Debugging string implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003-2019 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file debug/string 00026 * This file is a GNU debug extension to the Standard C++ Library. 00027 */ 00028 00029 #ifndef _GLIBCXX_DEBUG_STRING 00030 #define _GLIBCXX_DEBUG_STRING 1 00031 00032 #pragma GCC system_header 00033 00034 #include <string> 00035 #include <debug/safe_sequence.h> 00036 #include <debug/safe_container.h> 00037 #include <debug/safe_iterator.h> 00038 00039 #define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func) \ 00040 if (! (_Cond)) \ 00041 __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \ 00042 ._M_message(#_Cond)._M_error() 00043 00044 namespace __gnu_debug 00045 { 00046 /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 00047 template<typename _CharT, typename _Integer> 00048 inline const _CharT* 00049 __check_string(const _CharT* __s, 00050 _Integer __n __attribute__((__unused__)), 00051 const char* __file __attribute__((__unused__)), 00052 unsigned int __line __attribute__((__unused__)), 00053 const char* __function __attribute__((__unused__))) 00054 { 00055 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00056 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0, 00057 __file, __line, __function); 00058 #endif 00059 return __s; 00060 } 00061 00062 /** Checks that __s is non-NULL and then returns __s. */ 00063 template<typename _CharT> 00064 inline const _CharT* 00065 __check_string(const _CharT* __s, 00066 const char* __file __attribute__((__unused__)), 00067 unsigned int __line __attribute__((__unused__)), 00068 const char* __function __attribute__((__unused__))) 00069 { 00070 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00071 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0, 00072 __file, __line, __function); 00073 #endif 00074 return __s; 00075 } 00076 00077 #define __glibcxx_check_string_n_constructor(_Str, _Size) \ 00078 __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__) 00079 00080 #define __glibcxx_check_string_constructor(_Str) \ 00081 __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__) 00082 00083 /// Class std::basic_string with safety/checking/debug instrumentation. 00084 template<typename _CharT, typename _Traits = std::char_traits<_CharT>, 00085 typename _Allocator = std::allocator<_CharT> > 00086 class basic_string 00087 : public __gnu_debug::_Safe_container< 00088 basic_string<_CharT, _Traits, _Allocator>, 00089 _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>, 00090 public std::basic_string<_CharT, _Traits, _Allocator> 00091 { 00092 typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; 00093 typedef __gnu_debug::_Safe_container< 00094 basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)> 00095 _Safe; 00096 00097 template<typename _ItT, typename _SeqT, typename _CatT> 00098 friend class ::__gnu_debug::_Safe_iterator; 00099 00100 // type used for positions in insert, erase etc. 00101 typedef __gnu_debug::_Safe_iterator< 00102 typename _Base::__const_iterator, basic_string> __const_iterator; 00103 00104 public: 00105 // types: 00106 typedef _Traits traits_type; 00107 typedef typename _Traits::char_type value_type; 00108 typedef _Allocator allocator_type; 00109 typedef typename _Base::size_type size_type; 00110 typedef typename _Base::difference_type difference_type; 00111 typedef typename _Base::reference reference; 00112 typedef typename _Base::const_reference const_reference; 00113 typedef typename _Base::pointer pointer; 00114 typedef typename _Base::const_pointer const_pointer; 00115 00116 typedef __gnu_debug::_Safe_iterator< 00117 typename _Base::iterator, basic_string> iterator; 00118 typedef __gnu_debug::_Safe_iterator< 00119 typename _Base::const_iterator, basic_string> const_iterator; 00120 00121 typedef std::reverse_iterator<iterator> reverse_iterator; 00122 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00123 00124 using _Base::npos; 00125 00126 basic_string() 00127 _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value) 00128 : _Base() { } 00129 00130 // 21.3.1 construct/copy/destroy: 00131 explicit 00132 basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT 00133 : _Base(__a) { } 00134 00135 #if __cplusplus < 201103L 00136 basic_string(const basic_string& __str) 00137 : _Base(__str) { } 00138 00139 ~basic_string() { } 00140 #else 00141 basic_string(const basic_string&) = default; 00142 basic_string(basic_string&&) = default; 00143 00144 basic_string(std::initializer_list<_CharT> __l, 00145 const _Allocator& __a = _Allocator()) 00146 : _Base(__l, __a) 00147 { } 00148 00149 #if _GLIBCXX_USE_CXX11_ABI 00150 basic_string(const basic_string& __s, const _Allocator& __a) 00151 : _Base(__s, __a) { } 00152 00153 basic_string(basic_string&& __s, const _Allocator& __a) 00154 : _Base(std::move(__s), __a) { } 00155 #endif 00156 00157 ~basic_string() = default; 00158 00159 // Provides conversion from a normal-mode string to a debug-mode string 00160 basic_string(_Base&& __base) noexcept 00161 : _Base(std::move(__base)) { } 00162 #endif // C++11 00163 00164 // Provides conversion from a normal-mode string to a debug-mode string 00165 basic_string(const _Base& __base) 00166 : _Base(__base) { } 00167 00168 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00169 // 42. string ctors specify wrong default allocator 00170 basic_string(const basic_string& __str, size_type __pos, 00171 size_type __n = _Base::npos, 00172 const _Allocator& __a = _Allocator()) 00173 : _Base(__str, __pos, __n, __a) { } 00174 00175 basic_string(const _CharT* __s, size_type __n, 00176 const _Allocator& __a = _Allocator()) 00177 : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { } 00178 00179 basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) 00180 : _Base(__glibcxx_check_string_constructor(__s), __a) 00181 { this->assign(__s); } 00182 00183 basic_string(size_type __n, _CharT __c, 00184 const _Allocator& __a = _Allocator()) 00185 : _Base(__n, __c, __a) { } 00186 00187 template<typename _InputIterator> 00188 basic_string(_InputIterator __begin, _InputIterator __end, 00189 const _Allocator& __a = _Allocator()) 00190 : _Base(__gnu_debug::__base( 00191 __glibcxx_check_valid_constructor_range(__begin, __end)), 00192 __gnu_debug::__base(__end), __a) { } 00193 00194 #if __cplusplus < 201103L 00195 basic_string& 00196 operator=(const basic_string& __str) 00197 { 00198 this->_M_safe() = __str; 00199 _M_base() = __str; 00200 return *this; 00201 } 00202 #else 00203 basic_string& 00204 operator=(const basic_string&) = default; 00205 00206 basic_string& 00207 operator=(basic_string&&) = default; 00208 #endif 00209 00210 basic_string& 00211 operator=(const _CharT* __s) 00212 { 00213 __glibcxx_check_string(__s); 00214 _M_base() = __s; 00215 this->_M_invalidate_all(); 00216 return *this; 00217 } 00218 00219 basic_string& 00220 operator=(_CharT __c) 00221 { 00222 _M_base() = __c; 00223 this->_M_invalidate_all(); 00224 return *this; 00225 } 00226 00227 #if __cplusplus >= 201103L 00228 basic_string& 00229 operator=(std::initializer_list<_CharT> __l) 00230 { 00231 _M_base() = __l; 00232 this->_M_invalidate_all(); 00233 return *this; 00234 } 00235 #endif // C++11 00236 00237 // 21.3.2 iterators: 00238 iterator 00239 begin() // _GLIBCXX_NOEXCEPT 00240 { return iterator(_Base::begin(), this); } 00241 00242 const_iterator 00243 begin() const _GLIBCXX_NOEXCEPT 00244 { return const_iterator(_Base::begin(), this); } 00245 00246 iterator 00247 end() // _GLIBCXX_NOEXCEPT 00248 { return iterator(_Base::end(), this); } 00249 00250 const_iterator 00251 end() const _GLIBCXX_NOEXCEPT 00252 { return const_iterator(_Base::end(), this); } 00253 00254 reverse_iterator 00255 rbegin() // _GLIBCXX_NOEXCEPT 00256 { return reverse_iterator(end()); } 00257 00258 const_reverse_iterator 00259 rbegin() const _GLIBCXX_NOEXCEPT 00260 { return const_reverse_iterator(end()); } 00261 00262 reverse_iterator 00263 rend() // _GLIBCXX_NOEXCEPT 00264 { return reverse_iterator(begin()); } 00265 00266 const_reverse_iterator 00267 rend() const _GLIBCXX_NOEXCEPT 00268 { return const_reverse_iterator(begin()); } 00269 00270 #if __cplusplus >= 201103L 00271 const_iterator 00272 cbegin() const noexcept 00273 { return const_iterator(_Base::begin(), this); } 00274 00275 const_iterator 00276 cend() const noexcept 00277 { return const_iterator(_Base::end(), this); } 00278 00279 const_reverse_iterator 00280 crbegin() const noexcept 00281 { return const_reverse_iterator(end()); } 00282 00283 const_reverse_iterator 00284 crend() const noexcept 00285 { return const_reverse_iterator(begin()); } 00286 #endif 00287 00288 // 21.3.3 capacity: 00289 using _Base::size; 00290 using _Base::length; 00291 using _Base::max_size; 00292 00293 void 00294 resize(size_type __n, _CharT __c) 00295 { 00296 _Base::resize(__n, __c); 00297 this->_M_invalidate_all(); 00298 } 00299 00300 void 00301 resize(size_type __n) 00302 { this->resize(__n, _CharT()); } 00303 00304 #if __cplusplus >= 201103L 00305 void 00306 shrink_to_fit() noexcept 00307 { 00308 if (capacity() > size()) 00309 { 00310 __try 00311 { 00312 reserve(0); 00313 this->_M_invalidate_all(); 00314 } 00315 __catch(...) 00316 { } 00317 } 00318 } 00319 #endif 00320 00321 using _Base::capacity; 00322 using _Base::reserve; 00323 00324 void 00325 clear() // _GLIBCXX_NOEXCEPT 00326 { 00327 _Base::clear(); 00328 this->_M_invalidate_all(); 00329 } 00330 00331 using _Base::empty; 00332 00333 // 21.3.4 element access: 00334 const_reference 00335 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT 00336 { 00337 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 00338 _M_message(__gnu_debug::__msg_subscript_oob) 00339 ._M_sequence(*this, "this") 00340 ._M_integer(__pos, "__pos") 00341 ._M_integer(this->size(), "size")); 00342 return _M_base()[__pos]; 00343 } 00344 00345 reference 00346 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT 00347 { 00348 #if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC) 00349 __glibcxx_check_subscript(__pos); 00350 #else 00351 // as an extension v3 allows s[s.size()] when s is non-const. 00352 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 00353 _M_message(__gnu_debug::__msg_subscript_oob) 00354 ._M_sequence(*this, "this") 00355 ._M_integer(__pos, "__pos") 00356 ._M_integer(this->size(), "size")); 00357 #endif 00358 return _M_base()[__pos]; 00359 } 00360 00361 using _Base::at; 00362 00363 #if __cplusplus >= 201103L 00364 using _Base::front; 00365 using _Base::back; 00366 #endif 00367 00368 // 21.3.5 modifiers: 00369 basic_string& 00370 operator+=(const basic_string& __str) 00371 { 00372 _M_base() += __str; 00373 this->_M_invalidate_all(); 00374 return *this; 00375 } 00376 00377 basic_string& 00378 operator+=(const _CharT* __s) 00379 { 00380 __glibcxx_check_string(__s); 00381 _M_base() += __s; 00382 this->_M_invalidate_all(); 00383 return *this; 00384 } 00385 00386 basic_string& 00387 operator+=(_CharT __c) 00388 { 00389 _M_base() += __c; 00390 this->_M_invalidate_all(); 00391 return *this; 00392 } 00393 00394 #if __cplusplus >= 201103L 00395 basic_string& 00396 operator+=(std::initializer_list<_CharT> __l) 00397 { 00398 _M_base() += __l; 00399 this->_M_invalidate_all(); 00400 return *this; 00401 } 00402 #endif // C++11 00403 00404 basic_string& 00405 append(const basic_string& __str) 00406 { 00407 _Base::append(__str); 00408 this->_M_invalidate_all(); 00409 return *this; 00410 } 00411 00412 basic_string& 00413 append(const basic_string& __str, size_type __pos, size_type __n) 00414 { 00415 _Base::append(__str, __pos, __n); 00416 this->_M_invalidate_all(); 00417 return *this; 00418 } 00419 00420 basic_string& 00421 append(const _CharT* __s, size_type __n) 00422 { 00423 __glibcxx_check_string_len(__s, __n); 00424 _Base::append(__s, __n); 00425 this->_M_invalidate_all(); 00426 return *this; 00427 } 00428 00429 basic_string& 00430 append(const _CharT* __s) 00431 { 00432 __glibcxx_check_string(__s); 00433 _Base::append(__s); 00434 this->_M_invalidate_all(); 00435 return *this; 00436 } 00437 00438 basic_string& 00439 append(size_type __n, _CharT __c) 00440 { 00441 _Base::append(__n, __c); 00442 this->_M_invalidate_all(); 00443 return *this; 00444 } 00445 00446 template<typename _InputIterator> 00447 basic_string& 00448 append(_InputIterator __first, _InputIterator __last) 00449 { 00450 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00451 __glibcxx_check_valid_range2(__first, __last, __dist); 00452 00453 if (__dist.second >= __dp_sign) 00454 _Base::append(__gnu_debug::__unsafe(__first), 00455 __gnu_debug::__unsafe(__last)); 00456 else 00457 _Base::append(__first, __last); 00458 00459 this->_M_invalidate_all(); 00460 return *this; 00461 } 00462 00463 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00464 // 7. string clause minor problems 00465 void 00466 push_back(_CharT __c) 00467 { 00468 _Base::push_back(__c); 00469 this->_M_invalidate_all(); 00470 } 00471 00472 basic_string& 00473 assign(const basic_string& __x) 00474 { 00475 _Base::assign(__x); 00476 this->_M_invalidate_all(); 00477 return *this; 00478 } 00479 00480 #if __cplusplus >= 201103L 00481 basic_string& 00482 assign(basic_string&& __x) 00483 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x)))) 00484 { 00485 _Base::assign(std::move(__x)); 00486 this->_M_invalidate_all(); 00487 return *this; 00488 } 00489 #endif // C++11 00490 00491 basic_string& 00492 assign(const basic_string& __str, size_type __pos, size_type __n) 00493 { 00494 _Base::assign(__str, __pos, __n); 00495 this->_M_invalidate_all(); 00496 return *this; 00497 } 00498 00499 basic_string& 00500 assign(const _CharT* __s, size_type __n) 00501 { 00502 __glibcxx_check_string_len(__s, __n); 00503 _Base::assign(__s, __n); 00504 this->_M_invalidate_all(); 00505 return *this; 00506 } 00507 00508 basic_string& 00509 assign(const _CharT* __s) 00510 { 00511 __glibcxx_check_string(__s); 00512 _Base::assign(__s); 00513 this->_M_invalidate_all(); 00514 return *this; 00515 } 00516 00517 basic_string& 00518 assign(size_type __n, _CharT __c) 00519 { 00520 _Base::assign(__n, __c); 00521 this->_M_invalidate_all(); 00522 return *this; 00523 } 00524 00525 template<typename _InputIterator> 00526 basic_string& 00527 assign(_InputIterator __first, _InputIterator __last) 00528 { 00529 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00530 __glibcxx_check_valid_range2(__first, __last, __dist); 00531 00532 if (__dist.second >= __dp_sign) 00533 _Base::assign(__gnu_debug::__unsafe(__first), 00534 __gnu_debug::__unsafe(__last)); 00535 else 00536 _Base::assign(__first, __last); 00537 00538 this->_M_invalidate_all(); 00539 return *this; 00540 } 00541 00542 #if __cplusplus >= 201103L 00543 basic_string& 00544 assign(std::initializer_list<_CharT> __l) 00545 { 00546 _Base::assign(__l); 00547 this->_M_invalidate_all(); 00548 return *this; 00549 } 00550 #endif // C++11 00551 00552 basic_string& 00553 insert(size_type __pos1, const basic_string& __str) 00554 { 00555 _Base::insert(__pos1, __str); 00556 this->_M_invalidate_all(); 00557 return *this; 00558 } 00559 00560 basic_string& 00561 insert(size_type __pos1, const basic_string& __str, 00562 size_type __pos2, size_type __n) 00563 { 00564 _Base::insert(__pos1, __str, __pos2, __n); 00565 this->_M_invalidate_all(); 00566 return *this; 00567 } 00568 00569 basic_string& 00570 insert(size_type __pos, const _CharT* __s, size_type __n) 00571 { 00572 __glibcxx_check_string(__s); 00573 _Base::insert(__pos, __s, __n); 00574 this->_M_invalidate_all(); 00575 return *this; 00576 } 00577 00578 basic_string& 00579 insert(size_type __pos, const _CharT* __s) 00580 { 00581 __glibcxx_check_string(__s); 00582 _Base::insert(__pos, __s); 00583 this->_M_invalidate_all(); 00584 return *this; 00585 } 00586 00587 basic_string& 00588 insert(size_type __pos, size_type __n, _CharT __c) 00589 { 00590 _Base::insert(__pos, __n, __c); 00591 this->_M_invalidate_all(); 00592 return *this; 00593 } 00594 00595 iterator 00596 insert(__const_iterator __p, _CharT __c) 00597 { 00598 __glibcxx_check_insert(__p); 00599 typename _Base::iterator __res = _Base::insert(__p.base(), __c); 00600 this->_M_invalidate_all(); 00601 return iterator(__res, this); 00602 } 00603 00604 #if __cplusplus >= 201103L 00605 iterator 00606 insert(const_iterator __p, size_type __n, _CharT __c) 00607 { 00608 __glibcxx_check_insert(__p); 00609 #if _GLIBCXX_USE_CXX11_ABI 00610 typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c); 00611 #else 00612 const size_type __offset = __p.base() - _Base::cbegin(); 00613 _Base::insert(_Base::begin() + __offset, __n, __c); 00614 typename _Base::iterator __res = _Base::begin() + __offset; 00615 #endif 00616 this->_M_invalidate_all(); 00617 return iterator(__res, this); 00618 } 00619 #else 00620 void 00621 insert(iterator __p, size_type __n, _CharT __c) 00622 { 00623 __glibcxx_check_insert(__p); 00624 _Base::insert(__p.base(), __n, __c); 00625 this->_M_invalidate_all(); 00626 } 00627 #endif 00628 00629 template<typename _InputIterator> 00630 iterator 00631 insert(__const_iterator __p, 00632 _InputIterator __first, _InputIterator __last) 00633 { 00634 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00635 __glibcxx_check_insert_range(__p, __first, __last, __dist); 00636 00637 typename _Base::iterator __res; 00638 #if _GLIBCXX_USE_CXX11_ABI 00639 if (__dist.second >= __dp_sign) 00640 __res = _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), 00641 __gnu_debug::__unsafe(__last)); 00642 else 00643 __res = _Base::insert(__p.base(), __first, __last); 00644 #else 00645 const size_type __offset = __p.base() - _Base::begin(); 00646 _Base::insert(__p.base(), __first, __last); 00647 __res = _Base::begin() + __offset; 00648 #endif 00649 this->_M_invalidate_all(); 00650 return iterator(__res, this); 00651 } 00652 00653 #if __cplusplus >= 201103L 00654 iterator 00655 insert(const_iterator __p, std::initializer_list<_CharT> __l) 00656 { 00657 __glibcxx_check_insert(__p); 00658 #if _GLIBCXX_USE_CXX11_ABI 00659 const auto __res = _Base::insert(__p.base(), __l); 00660 #else 00661 const size_type __offset = __p.base() - _Base::cbegin(); 00662 _Base::insert(_Base::begin() + __offset, __l); 00663 auto __res = _Base::begin() + __offset; 00664 #endif 00665 this->_M_invalidate_all(); 00666 return iterator(__res, this); 00667 } 00668 #endif // C++11 00669 00670 basic_string& 00671 erase(size_type __pos = 0, size_type __n = _Base::npos) 00672 { 00673 _Base::erase(__pos, __n); 00674 this->_M_invalidate_all(); 00675 return *this; 00676 } 00677 00678 iterator 00679 erase(iterator __position) 00680 { 00681 __glibcxx_check_erase(__position); 00682 typename _Base::iterator __res = _Base::erase(__position.base()); 00683 this->_M_invalidate_all(); 00684 return iterator(__res, this); 00685 } 00686 00687 iterator 00688 erase(iterator __first, iterator __last) 00689 { 00690 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00691 // 151. can't currently clear() empty container 00692 __glibcxx_check_erase_range(__first, __last); 00693 typename _Base::iterator __res = _Base::erase(__first.base(), 00694 __last.base()); 00695 this->_M_invalidate_all(); 00696 return iterator(__res, this); 00697 } 00698 00699 #if __cplusplus >= 201103L 00700 void 00701 pop_back() // noexcept 00702 { 00703 __glibcxx_check_nonempty(); 00704 _Base::pop_back(); 00705 this->_M_invalidate_all(); 00706 } 00707 #endif // C++11 00708 00709 basic_string& 00710 replace(size_type __pos1, size_type __n1, const basic_string& __str) 00711 { 00712 _Base::replace(__pos1, __n1, __str); 00713 this->_M_invalidate_all(); 00714 return *this; 00715 } 00716 00717 basic_string& 00718 replace(size_type __pos1, size_type __n1, const basic_string& __str, 00719 size_type __pos2, size_type __n2) 00720 { 00721 _Base::replace(__pos1, __n1, __str, __pos2, __n2); 00722 this->_M_invalidate_all(); 00723 return *this; 00724 } 00725 00726 basic_string& 00727 replace(size_type __pos, size_type __n1, const _CharT* __s, 00728 size_type __n2) 00729 { 00730 __glibcxx_check_string_len(__s, __n2); 00731 _Base::replace(__pos, __n1, __s, __n2); 00732 this->_M_invalidate_all(); 00733 return *this; 00734 } 00735 00736 basic_string& 00737 replace(size_type __pos, size_type __n1, const _CharT* __s) 00738 { 00739 __glibcxx_check_string(__s); 00740 _Base::replace(__pos, __n1, __s); 00741 this->_M_invalidate_all(); 00742 return *this; 00743 } 00744 00745 basic_string& 00746 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) 00747 { 00748 _Base::replace(__pos, __n1, __n2, __c); 00749 this->_M_invalidate_all(); 00750 return *this; 00751 } 00752 00753 basic_string& 00754 replace(__const_iterator __i1, __const_iterator __i2, 00755 const basic_string& __str) 00756 { 00757 __glibcxx_check_erase_range(__i1, __i2); 00758 _Base::replace(__i1.base(), __i2.base(), __str); 00759 this->_M_invalidate_all(); 00760 return *this; 00761 } 00762 00763 basic_string& 00764 replace(__const_iterator __i1, __const_iterator __i2, 00765 const _CharT* __s, size_type __n) 00766 { 00767 __glibcxx_check_erase_range(__i1, __i2); 00768 __glibcxx_check_string_len(__s, __n); 00769 _Base::replace(__i1.base(), __i2.base(), __s, __n); 00770 this->_M_invalidate_all(); 00771 return *this; 00772 } 00773 00774 basic_string& 00775 replace(__const_iterator __i1, __const_iterator __i2, 00776 const _CharT* __s) 00777 { 00778 __glibcxx_check_erase_range(__i1, __i2); 00779 __glibcxx_check_string(__s); 00780 _Base::replace(__i1.base(), __i2.base(), __s); 00781 this->_M_invalidate_all(); 00782 return *this; 00783 } 00784 00785 basic_string& 00786 replace(__const_iterator __i1, __const_iterator __i2, 00787 size_type __n, _CharT __c) 00788 { 00789 __glibcxx_check_erase_range(__i1, __i2); 00790 _Base::replace(__i1.base(), __i2.base(), __n, __c); 00791 this->_M_invalidate_all(); 00792 return *this; 00793 } 00794 00795 template<typename _InputIterator> 00796 basic_string& 00797 replace(__const_iterator __i1, __const_iterator __i2, 00798 _InputIterator __j1, _InputIterator __j2) 00799 { 00800 __glibcxx_check_erase_range(__i1, __i2); 00801 00802 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 00803 __glibcxx_check_valid_range2(__j1, __j2, __dist); 00804 00805 if (__dist.second >= __dp_sign) 00806 _Base::replace(__i1.base(), __i2.base(), 00807 __gnu_debug::__unsafe(__j1), 00808 __gnu_debug::__unsafe(__j2)); 00809 else 00810 _Base::replace(__i1.base(), __i2.base(), __j1, __j2); 00811 00812 this->_M_invalidate_all(); 00813 return *this; 00814 } 00815 00816 #if __cplusplus >= 201103L 00817 basic_string& 00818 replace(__const_iterator __i1, __const_iterator __i2, 00819 std::initializer_list<_CharT> __l) 00820 { 00821 __glibcxx_check_erase_range(__i1, __i2); 00822 _Base::replace(__i1.base(), __i2.base(), __l); 00823 this->_M_invalidate_all(); 00824 return *this; 00825 } 00826 #endif // C++11 00827 00828 size_type 00829 copy(_CharT* __s, size_type __n, size_type __pos = 0) const 00830 { 00831 __glibcxx_check_string_len(__s, __n); 00832 return _Base::copy(__s, __n, __pos); 00833 } 00834 00835 void 00836 swap(basic_string& __x) 00837 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value) 00838 { 00839 _Safe::_M_swap(__x); 00840 _Base::swap(__x); 00841 } 00842 00843 // 21.3.6 string operations: 00844 const _CharT* 00845 c_str() const _GLIBCXX_NOEXCEPT 00846 { 00847 const _CharT* __res = _Base::c_str(); 00848 this->_M_invalidate_all(); 00849 return __res; 00850 } 00851 00852 const _CharT* 00853 data() const _GLIBCXX_NOEXCEPT 00854 { 00855 const _CharT* __res = _Base::data(); 00856 this->_M_invalidate_all(); 00857 return __res; 00858 } 00859 00860 using _Base::get_allocator; 00861 00862 size_type 00863 find(const basic_string& __str, size_type __pos = 0) const 00864 _GLIBCXX_NOEXCEPT 00865 { return _Base::find(__str, __pos); } 00866 00867 size_type 00868 find(const _CharT* __s, size_type __pos, size_type __n) const 00869 { 00870 __glibcxx_check_string(__s); 00871 return _Base::find(__s, __pos, __n); 00872 } 00873 00874 size_type 00875 find(const _CharT* __s, size_type __pos = 0) const 00876 { 00877 __glibcxx_check_string(__s); 00878 return _Base::find(__s, __pos); 00879 } 00880 00881 size_type 00882 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 00883 { return _Base::find(__c, __pos); } 00884 00885 size_type 00886 rfind(const basic_string& __str, size_type __pos = _Base::npos) const 00887 _GLIBCXX_NOEXCEPT 00888 { return _Base::rfind(__str, __pos); } 00889 00890 size_type 00891 rfind(const _CharT* __s, size_type __pos, size_type __n) const 00892 { 00893 __glibcxx_check_string_len(__s, __n); 00894 return _Base::rfind(__s, __pos, __n); 00895 } 00896 00897 size_type 00898 rfind(const _CharT* __s, size_type __pos = _Base::npos) const 00899 { 00900 __glibcxx_check_string(__s); 00901 return _Base::rfind(__s, __pos); 00902 } 00903 00904 size_type 00905 rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 00906 { return _Base::rfind(__c, __pos); } 00907 00908 size_type 00909 find_first_of(const basic_string& __str, size_type __pos = 0) const 00910 _GLIBCXX_NOEXCEPT 00911 { return _Base::find_first_of(__str, __pos); } 00912 00913 size_type 00914 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 00915 { 00916 __glibcxx_check_string(__s); 00917 return _Base::find_first_of(__s, __pos, __n); 00918 } 00919 00920 size_type 00921 find_first_of(const _CharT* __s, size_type __pos = 0) const 00922 { 00923 __glibcxx_check_string(__s); 00924 return _Base::find_first_of(__s, __pos); 00925 } 00926 00927 size_type 00928 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 00929 { return _Base::find_first_of(__c, __pos); } 00930 00931 size_type 00932 find_last_of(const basic_string& __str, 00933 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 00934 { return _Base::find_last_of(__str, __pos); } 00935 00936 size_type 00937 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 00938 { 00939 __glibcxx_check_string(__s); 00940 return _Base::find_last_of(__s, __pos, __n); 00941 } 00942 00943 size_type 00944 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const 00945 { 00946 __glibcxx_check_string(__s); 00947 return _Base::find_last_of(__s, __pos); 00948 } 00949 00950 size_type 00951 find_last_of(_CharT __c, size_type __pos = _Base::npos) const 00952 _GLIBCXX_NOEXCEPT 00953 { return _Base::find_last_of(__c, __pos); } 00954 00955 size_type 00956 find_first_not_of(const basic_string& __str, size_type __pos = 0) const 00957 _GLIBCXX_NOEXCEPT 00958 { return _Base::find_first_not_of(__str, __pos); } 00959 00960 size_type 00961 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00962 { 00963 __glibcxx_check_string_len(__s, __n); 00964 return _Base::find_first_not_of(__s, __pos, __n); 00965 } 00966 00967 size_type 00968 find_first_not_of(const _CharT* __s, size_type __pos = 0) const 00969 { 00970 __glibcxx_check_string(__s); 00971 return _Base::find_first_not_of(__s, __pos); 00972 } 00973 00974 size_type 00975 find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 00976 { return _Base::find_first_not_of(__c, __pos); } 00977 00978 size_type 00979 find_last_not_of(const basic_string& __str, 00980 size_type __pos = _Base::npos) const 00981 _GLIBCXX_NOEXCEPT 00982 { return _Base::find_last_not_of(__str, __pos); } 00983 00984 size_type 00985 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00986 { 00987 __glibcxx_check_string(__s); 00988 return _Base::find_last_not_of(__s, __pos, __n); 00989 } 00990 00991 size_type 00992 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const 00993 { 00994 __glibcxx_check_string(__s); 00995 return _Base::find_last_not_of(__s, __pos); 00996 } 00997 00998 size_type 00999 find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const 01000 _GLIBCXX_NOEXCEPT 01001 { return _Base::find_last_not_of(__c, __pos); } 01002 01003 basic_string 01004 substr(size_type __pos = 0, size_type __n = _Base::npos) const 01005 { return basic_string(_Base::substr(__pos, __n)); } 01006 01007 int 01008 compare(const basic_string& __str) const 01009 { return _Base::compare(__str); } 01010 01011 int 01012 compare(size_type __pos1, size_type __n1, 01013 const basic_string& __str) const 01014 { return _Base::compare(__pos1, __n1, __str); } 01015 01016 int 01017 compare(size_type __pos1, size_type __n1, const basic_string& __str, 01018 size_type __pos2, size_type __n2) const 01019 { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } 01020 01021 int 01022 compare(const _CharT* __s) const 01023 { 01024 __glibcxx_check_string(__s); 01025 return _Base::compare(__s); 01026 } 01027 01028 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01029 // 5. string::compare specification questionable 01030 int 01031 compare(size_type __pos1, size_type __n1, const _CharT* __s) const 01032 { 01033 __glibcxx_check_string(__s); 01034 return _Base::compare(__pos1, __n1, __s); 01035 } 01036 01037 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01038 // 5. string::compare specification questionable 01039 int 01040 compare(size_type __pos1, size_type __n1,const _CharT* __s, 01041 size_type __n2) const 01042 { 01043 __glibcxx_check_string_len(__s, __n2); 01044 return _Base::compare(__pos1, __n1, __s, __n2); 01045 } 01046 01047 _Base& 01048 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 01049 01050 const _Base& 01051 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 01052 01053 using _Safe::_M_invalidate_all; 01054 }; 01055 01056 template<typename _CharT, typename _Traits, typename _Allocator> 01057 inline basic_string<_CharT,_Traits,_Allocator> 01058 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01059 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01060 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 01061 01062 template<typename _CharT, typename _Traits, typename _Allocator> 01063 inline basic_string<_CharT,_Traits,_Allocator> 01064 operator+(const _CharT* __lhs, 01065 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01066 { 01067 __glibcxx_check_string(__lhs); 01068 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 01069 } 01070 01071 template<typename _CharT, typename _Traits, typename _Allocator> 01072 inline basic_string<_CharT,_Traits,_Allocator> 01073 operator+(_CharT __lhs, 01074 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01075 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } 01076 01077 template<typename _CharT, typename _Traits, typename _Allocator> 01078 inline basic_string<_CharT,_Traits,_Allocator> 01079 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01080 const _CharT* __rhs) 01081 { 01082 __glibcxx_check_string(__rhs); 01083 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 01084 } 01085 01086 template<typename _CharT, typename _Traits, typename _Allocator> 01087 inline basic_string<_CharT,_Traits,_Allocator> 01088 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01089 _CharT __rhs) 01090 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 01091 01092 template<typename _CharT, typename _Traits, typename _Allocator> 01093 inline bool 01094 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01095 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01096 { return __lhs._M_base() == __rhs._M_base(); } 01097 01098 template<typename _CharT, typename _Traits, typename _Allocator> 01099 inline bool 01100 operator==(const _CharT* __lhs, 01101 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01102 { 01103 __glibcxx_check_string(__lhs); 01104 return __lhs == __rhs._M_base(); 01105 } 01106 01107 template<typename _CharT, typename _Traits, typename _Allocator> 01108 inline bool 01109 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01110 const _CharT* __rhs) 01111 { 01112 __glibcxx_check_string(__rhs); 01113 return __lhs._M_base() == __rhs; 01114 } 01115 01116 template<typename _CharT, typename _Traits, typename _Allocator> 01117 inline bool 01118 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01119 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01120 { return __lhs._M_base() != __rhs._M_base(); } 01121 01122 template<typename _CharT, typename _Traits, typename _Allocator> 01123 inline bool 01124 operator!=(const _CharT* __lhs, 01125 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01126 { 01127 __glibcxx_check_string(__lhs); 01128 return __lhs != __rhs._M_base(); 01129 } 01130 01131 template<typename _CharT, typename _Traits, typename _Allocator> 01132 inline bool 01133 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01134 const _CharT* __rhs) 01135 { 01136 __glibcxx_check_string(__rhs); 01137 return __lhs._M_base() != __rhs; 01138 } 01139 01140 template<typename _CharT, typename _Traits, typename _Allocator> 01141 inline bool 01142 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01143 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01144 { return __lhs._M_base() < __rhs._M_base(); } 01145 01146 template<typename _CharT, typename _Traits, typename _Allocator> 01147 inline bool 01148 operator<(const _CharT* __lhs, 01149 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01150 { 01151 __glibcxx_check_string(__lhs); 01152 return __lhs < __rhs._M_base(); 01153 } 01154 01155 template<typename _CharT, typename _Traits, typename _Allocator> 01156 inline bool 01157 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01158 const _CharT* __rhs) 01159 { 01160 __glibcxx_check_string(__rhs); 01161 return __lhs._M_base() < __rhs; 01162 } 01163 01164 template<typename _CharT, typename _Traits, typename _Allocator> 01165 inline bool 01166 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01167 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01168 { return __lhs._M_base() <= __rhs._M_base(); } 01169 01170 template<typename _CharT, typename _Traits, typename _Allocator> 01171 inline bool 01172 operator<=(const _CharT* __lhs, 01173 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01174 { 01175 __glibcxx_check_string(__lhs); 01176 return __lhs <= __rhs._M_base(); 01177 } 01178 01179 template<typename _CharT, typename _Traits, typename _Allocator> 01180 inline bool 01181 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01182 const _CharT* __rhs) 01183 { 01184 __glibcxx_check_string(__rhs); 01185 return __lhs._M_base() <= __rhs; 01186 } 01187 01188 template<typename _CharT, typename _Traits, typename _Allocator> 01189 inline bool 01190 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01191 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01192 { return __lhs._M_base() >= __rhs._M_base(); } 01193 01194 template<typename _CharT, typename _Traits, typename _Allocator> 01195 inline bool 01196 operator>=(const _CharT* __lhs, 01197 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01198 { 01199 __glibcxx_check_string(__lhs); 01200 return __lhs >= __rhs._M_base(); 01201 } 01202 01203 template<typename _CharT, typename _Traits, typename _Allocator> 01204 inline bool 01205 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01206 const _CharT* __rhs) 01207 { 01208 __glibcxx_check_string(__rhs); 01209 return __lhs._M_base() >= __rhs; 01210 } 01211 01212 template<typename _CharT, typename _Traits, typename _Allocator> 01213 inline bool 01214 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01215 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01216 { return __lhs._M_base() > __rhs._M_base(); } 01217 01218 template<typename _CharT, typename _Traits, typename _Allocator> 01219 inline bool 01220 operator>(const _CharT* __lhs, 01221 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 01222 { 01223 __glibcxx_check_string(__lhs); 01224 return __lhs > __rhs._M_base(); 01225 } 01226 01227 template<typename _CharT, typename _Traits, typename _Allocator> 01228 inline bool 01229 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 01230 const _CharT* __rhs) 01231 { 01232 __glibcxx_check_string(__rhs); 01233 return __lhs._M_base() > __rhs; 01234 } 01235 01236 // 21.3.7.8: 01237 template<typename _CharT, typename _Traits, typename _Allocator> 01238 inline void 01239 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, 01240 basic_string<_CharT,_Traits,_Allocator>& __rhs) 01241 { __lhs.swap(__rhs); } 01242 01243 template<typename _CharT, typename _Traits, typename _Allocator> 01244 std::basic_ostream<_CharT, _Traits>& 01245 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01246 const basic_string<_CharT, _Traits, _Allocator>& __str) 01247 { return __os << __str._M_base(); } 01248 01249 template<typename _CharT, typename _Traits, typename _Allocator> 01250 std::basic_istream<_CharT,_Traits>& 01251 operator>>(std::basic_istream<_CharT,_Traits>& __is, 01252 basic_string<_CharT,_Traits,_Allocator>& __str) 01253 { 01254 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); 01255 __str._M_invalidate_all(); 01256 return __res; 01257 } 01258 01259 template<typename _CharT, typename _Traits, typename _Allocator> 01260 std::basic_istream<_CharT,_Traits>& 01261 getline(std::basic_istream<_CharT,_Traits>& __is, 01262 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) 01263 { 01264 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 01265 __str._M_base(), 01266 __delim); 01267 __str._M_invalidate_all(); 01268 return __res; 01269 } 01270 01271 template<typename _CharT, typename _Traits, typename _Allocator> 01272 std::basic_istream<_CharT,_Traits>& 01273 getline(std::basic_istream<_CharT,_Traits>& __is, 01274 basic_string<_CharT,_Traits,_Allocator>& __str) 01275 { 01276 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 01277 __str._M_base()); 01278 __str._M_invalidate_all(); 01279 return __res; 01280 } 01281 01282 typedef basic_string<char> string; 01283 01284 #ifdef _GLIBCXX_USE_WCHAR_T 01285 typedef basic_string<wchar_t> wstring; 01286 #endif 01287 01288 template<typename _CharT, typename _Traits, typename _Allocator> 01289 struct _Insert_range_from_self_is_safe< 01290 __gnu_debug::basic_string<_CharT, _Traits, _Allocator> > 01291 { enum { __value = 1 }; }; 01292 01293 } // namespace __gnu_debug 01294 01295 #endif