1// Debugging string implementation -*- C++ -*- 2 3// Copyright (C) 2003-2022 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file debug/string 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29#ifndef _GLIBCXX_DEBUG_STRING 30#define _GLIBCXX_DEBUG_STRING 1 31 32#pragma GCC system_header 33 34#include <string> 35#include <debug/safe_sequence.h> 36#include <debug/safe_container.h> 37#include <debug/safe_iterator.h> 38 39#define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func) \ 40 if (! (_Cond)) \ 41 __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \ 42 ._M_message(#_Cond)._M_error() 43 44#if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103 45# define _GLIBCXX_INSERT_RETURNS_ITERATOR 1 46# define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) expr 47#else 48# define _GLIBCXX_INSERT_RETURNS_ITERATOR 0 49# define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) 50#endif 51 52namespace __gnu_debug 53{ 54 /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 55 template<typename _CharT, typename _Integer> 56 inline const _CharT* 57 __check_string(const _CharT* __s, 58 _Integer __n __attribute__((__unused__)), 59 const char* __file __attribute__((__unused__)), 60 unsigned int __line __attribute__((__unused__)), 61 const char* __function __attribute__((__unused__))) 62 { 63#ifdef _GLIBCXX_DEBUG_PEDANTIC 64 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0, 65 __file, __line, __function); 66#endif 67 return __s; 68 } 69 70 /** Checks that __s is non-NULL and then returns __s. */ 71 template<typename _CharT> 72 inline const _CharT* 73 __check_string(const _CharT* __s, 74 const char* __file __attribute__((__unused__)), 75 unsigned int __line __attribute__((__unused__)), 76 const char* __function __attribute__((__unused__))) 77 { 78#ifdef _GLIBCXX_DEBUG_PEDANTIC 79 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0, 80 __file, __line, __function); 81#endif 82 return __s; 83 } 84 85#define __glibcxx_check_string_n_constructor(_Str, _Size) \ 86 __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__) 87 88#define __glibcxx_check_string_constructor(_Str) \ 89 __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__) 90 91 /// Class std::basic_string with safety/checking/debug instrumentation. 92 template<typename _CharT, typename _Traits = std::char_traits<_CharT>, 93 typename _Allocator = std::allocator<_CharT> > 94 class basic_string 95 : public __gnu_debug::_Safe_container< 96 basic_string<_CharT, _Traits, _Allocator>, 97 _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>, 98 public std::basic_string<_CharT, _Traits, _Allocator> 99 { 100 typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; 101 typedef __gnu_debug::_Safe_container< 102 basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)> 103 _Safe; 104 105 template<typename _ItT, typename _SeqT, typename _CatT> 106 friend class ::__gnu_debug::_Safe_iterator; 107 108 // type used for positions in insert, erase etc. 109 typedef __gnu_debug::_Safe_iterator< 110 typename _Base::__const_iterator, basic_string> __const_iterator; 111 112 public: 113 // types: 114 typedef _Traits traits_type; 115 typedef typename _Traits::char_type value_type; 116 typedef _Allocator allocator_type; 117 typedef typename _Base::size_type size_type; 118 typedef typename _Base::difference_type difference_type; 119 typedef typename _Base::reference reference; 120 typedef typename _Base::const_reference const_reference; 121 typedef typename _Base::pointer pointer; 122 typedef typename _Base::const_pointer const_pointer; 123 124 typedef __gnu_debug::_Safe_iterator< 125 typename _Base::iterator, basic_string> iterator; 126 typedef __gnu_debug::_Safe_iterator< 127 typename _Base::const_iterator, basic_string> const_iterator; 128 129 typedef std::reverse_iterator<iterator> reverse_iterator; 130 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 131 132 using _Base::npos; 133 134 // 21.3.1 construct/copy/destroy: 135 136 explicit 137 basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT 138 : _Base(__a) { } 139 140#if __cplusplus < 201103L 141 basic_string() : _Base() { } 142 143 basic_string(const basic_string& __str) 144 : _Base(__str) { } 145 146 ~basic_string() { } 147#else 148 basic_string() = default; 149 basic_string(const basic_string&) = default; 150 basic_string(basic_string&&) = default; 151 152 basic_string(std::initializer_list<_CharT> __l, 153 const _Allocator& __a = _Allocator()) 154 : _Base(__l, __a) 155 { } 156 157 basic_string(const basic_string& __s, const _Allocator& __a) 158 : _Base(__s, __a) { } 159 160 basic_string(basic_string&& __s, const _Allocator& __a) 161 noexcept( 162 std::is_nothrow_constructible<_Base, _Base, const _Allocator&>::value ) 163 : _Safe(std::move(__s), __a), 164 _Base(std::move(__s), __a) 165 { } 166 167 ~basic_string() = default; 168 169 // Provides conversion from a normal-mode string to a debug-mode string 170 basic_string(_Base&& __base) noexcept 171 : _Base(std::move(__base)) { } 172#endif // C++11 173 174 // Provides conversion from a normal-mode string to a debug-mode string 175 basic_string(const _Base& __base) 176 : _Base(__base) { } 177 178 // _GLIBCXX_RESOLVE_LIB_DEFECTS 179 // 42. string ctors specify wrong default allocator 180 basic_string(const basic_string& __str, size_type __pos, 181 size_type __n = _Base::npos, 182 const _Allocator& __a = _Allocator()) 183 : _Base(__str, __pos, __n, __a) { } 184 185 basic_string(const _CharT* __s, size_type __n, 186 const _Allocator& __a = _Allocator()) 187 : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { } 188 189 basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) 190 : _Base(__glibcxx_check_string_constructor(__s), __a) 191 { } 192 193 basic_string(size_type __n, _CharT __c, 194 const _Allocator& __a = _Allocator()) 195 : _Base(__n, __c, __a) { } 196 197 template<typename _InputIterator> 198 basic_string(_InputIterator __begin, _InputIterator __end, 199 const _Allocator& __a = _Allocator()) 200 : _Base(__gnu_debug::__base( 201 __glibcxx_check_valid_constructor_range(__begin, __end)), 202 __gnu_debug::__base(__end), __a) { } 203 204#if __cplusplus >= 201103L 205 basic_string& 206 operator=(const basic_string&) = default; 207 208 basic_string& 209 operator=(basic_string&&) = default; 210#endif 211 212 basic_string& 213 operator=(const _CharT* __s) 214 { 215 __glibcxx_check_string(__s); 216 _Base::operator=(__s); 217 this->_M_invalidate_all(); 218 return *this; 219 } 220 221 basic_string& 222 operator=(_CharT __c) 223 { 224 _Base::operator=(__c); 225 this->_M_invalidate_all(); 226 return *this; 227 } 228 229#if __cplusplus >= 201103L 230 basic_string& 231 operator=(std::initializer_list<_CharT> __l) 232 { 233 _Base::operator=(__l); 234 this->_M_invalidate_all(); 235 return *this; 236 } 237#endif // C++11 238 239 // 21.3.2 iterators: 240 iterator 241 begin() // _GLIBCXX_NOEXCEPT 242 { return iterator(_Base::begin(), this); } 243 244 const_iterator 245 begin() const _GLIBCXX_NOEXCEPT 246 { return const_iterator(_Base::begin(), this); } 247 248 iterator 249 end() // _GLIBCXX_NOEXCEPT 250 { return iterator(_Base::end(), this); } 251 252 const_iterator 253 end() const _GLIBCXX_NOEXCEPT 254 { return const_iterator(_Base::end(), this); } 255 256 reverse_iterator 257 rbegin() // _GLIBCXX_NOEXCEPT 258 { return reverse_iterator(end()); } 259 260 const_reverse_iterator 261 rbegin() const _GLIBCXX_NOEXCEPT 262 { return const_reverse_iterator(end()); } 263 264 reverse_iterator 265 rend() // _GLIBCXX_NOEXCEPT 266 { return reverse_iterator(begin()); } 267 268 const_reverse_iterator 269 rend() const _GLIBCXX_NOEXCEPT 270 { return const_reverse_iterator(begin()); } 271 272#if __cplusplus >= 201103L 273 const_iterator 274 cbegin() const noexcept 275 { return const_iterator(_Base::begin(), this); } 276 277 const_iterator 278 cend() const noexcept 279 { return const_iterator(_Base::end(), this); } 280 281 const_reverse_iterator 282 crbegin() const noexcept 283 { return const_reverse_iterator(end()); } 284 285 const_reverse_iterator 286 crend() const noexcept 287 { return const_reverse_iterator(begin()); } 288#endif 289 290 // 21.3.3 capacity: 291 using _Base::size; 292 using _Base::length; 293 using _Base::max_size; 294 295 void 296 resize(size_type __n, _CharT __c) 297 { 298 _Base::resize(__n, __c); 299 this->_M_invalidate_all(); 300 } 301 302 void 303 resize(size_type __n) 304 { this->resize(__n, _CharT()); } 305 306#if __cplusplus >= 201103L 307 void 308 shrink_to_fit() noexcept 309 { 310 if (capacity() > size()) 311 { 312 __try 313 { 314 reserve(0); 315 this->_M_invalidate_all(); 316 } 317 __catch(...) 318 { } 319 } 320 } 321#endif 322 323 using _Base::capacity; 324 using _Base::reserve; 325 326 void 327 clear() // _GLIBCXX_NOEXCEPT 328 { 329 _Base::clear(); 330 this->_M_invalidate_all(); 331 } 332 333 using _Base::empty; 334 335 // 21.3.4 element access: 336 const_reference 337 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT 338 { 339 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 340 _M_message(__gnu_debug::__msg_subscript_oob) 341 ._M_sequence(*this, "this") 342 ._M_integer(__pos, "__pos") 343 ._M_integer(this->size(), "size")); 344 return _Base::operator[](__pos); 345 } 346 347 reference 348 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT 349 { 350#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC) 351 __glibcxx_check_subscript(__pos); 352#else 353 // as an extension v3 allows s[s.size()] when s is non-const. 354 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 355 _M_message(__gnu_debug::__msg_subscript_oob) 356 ._M_sequence(*this, "this") 357 ._M_integer(__pos, "__pos") 358 ._M_integer(this->size(), "size")); 359#endif 360 return _Base::operator[](__pos); 361 } 362 363 using _Base::at; 364 365#if __cplusplus >= 201103L 366 using _Base::front; 367 using _Base::back; 368#endif 369 370 // 21.3.5 modifiers: 371 basic_string& 372 operator+=(const basic_string& __str) 373 { 374 _Base::operator+=(__str); 375 this->_M_invalidate_all(); 376 return *this; 377 } 378 379 basic_string& 380 operator+=(const _CharT* __s) 381 { 382 __glibcxx_check_string(__s); 383 _Base::operator+=(__s); 384 this->_M_invalidate_all(); 385 return *this; 386 } 387 388 basic_string& 389 operator+=(_CharT __c) 390 { 391 _Base::operator+=(__c); 392 this->_M_invalidate_all(); 393 return *this; 394 } 395 396#if __cplusplus >= 201103L 397 basic_string& 398 operator+=(std::initializer_list<_CharT> __l) 399 { 400 _Base::operator+=(__l); 401 this->_M_invalidate_all(); 402 return *this; 403 } 404#endif // C++11 405 406 basic_string& 407 append(const basic_string& __str) 408 { 409 _Base::append(__str); 410 this->_M_invalidate_all(); 411 return *this; 412 } 413 414 basic_string& 415 append(const basic_string& __str, size_type __pos, size_type __n) 416 { 417 _Base::append(__str, __pos, __n); 418 this->_M_invalidate_all(); 419 return *this; 420 } 421 422 basic_string& 423 append(const _CharT* __s, size_type __n) 424 { 425 __glibcxx_check_string_len(__s, __n); 426 _Base::append(__s, __n); 427 this->_M_invalidate_all(); 428 return *this; 429 } 430 431 basic_string& 432 append(const _CharT* __s) 433 { 434 __glibcxx_check_string(__s); 435 _Base::append(__s); 436 this->_M_invalidate_all(); 437 return *this; 438 } 439 440 basic_string& 441 append(size_type __n, _CharT __c) 442 { 443 _Base::append(__n, __c); 444 this->_M_invalidate_all(); 445 return *this; 446 } 447 448 template<typename _InputIterator> 449 basic_string& 450 append(_InputIterator __first, _InputIterator __last) 451 { 452 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 453 __glibcxx_check_valid_range2(__first, __last, __dist); 454 455 if (__dist.second >= __dp_sign) 456 _Base::append(__gnu_debug::__unsafe(__first), 457 __gnu_debug::__unsafe(__last)); 458 else 459 _Base::append(__first, __last); 460 461 this->_M_invalidate_all(); 462 return *this; 463 } 464 465 // _GLIBCXX_RESOLVE_LIB_DEFECTS 466 // 7. string clause minor problems 467 void 468 push_back(_CharT __c) 469 { 470 _Base::push_back(__c); 471 this->_M_invalidate_all(); 472 } 473 474 basic_string& 475 assign(const basic_string& __x) 476 { 477 _Base::assign(__x); 478 this->_M_invalidate_all(); 479 return *this; 480 } 481 482#if __cplusplus >= 201103L 483 basic_string& 484 assign(basic_string&& __x) 485 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x)))) 486 { 487 _Base::assign(std::move(__x)); 488 this->_M_invalidate_all(); 489 return *this; 490 } 491#endif // C++11 492 493 basic_string& 494 assign(const basic_string& __str, size_type __pos, size_type __n) 495 { 496 _Base::assign(__str, __pos, __n); 497 this->_M_invalidate_all(); 498 return *this; 499 } 500 501 basic_string& 502 assign(const _CharT* __s, size_type __n) 503 { 504 __glibcxx_check_string_len(__s, __n); 505 _Base::assign(__s, __n); 506 this->_M_invalidate_all(); 507 return *this; 508 } 509 510 basic_string& 511 assign(const _CharT* __s) 512 { 513 __glibcxx_check_string(__s); 514 _Base::assign(__s); 515 this->_M_invalidate_all(); 516 return *this; 517 } 518 519 basic_string& 520 assign(size_type __n, _CharT __c) 521 { 522 _Base::assign(__n, __c); 523 this->_M_invalidate_all(); 524 return *this; 525 } 526 527 template<typename _InputIterator> 528 basic_string& 529 assign(_InputIterator __first, _InputIterator __last) 530 { 531 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 532 __glibcxx_check_valid_range2(__first, __last, __dist); 533 534 if (__dist.second >= __dp_sign) 535 _Base::assign(__gnu_debug::__unsafe(__first), 536 __gnu_debug::__unsafe(__last)); 537 else 538 _Base::assign(__first, __last); 539 540 this->_M_invalidate_all(); 541 return *this; 542 } 543 544#if __cplusplus >= 201103L 545 basic_string& 546 assign(std::initializer_list<_CharT> __l) 547 { 548 _Base::assign(__l); 549 this->_M_invalidate_all(); 550 return *this; 551 } 552#endif // C++11 553 554 basic_string& 555 insert(size_type __pos1, const basic_string& __str) 556 { 557 _Base::insert(__pos1, __str); 558 this->_M_invalidate_all(); 559 return *this; 560 } 561 562 basic_string& 563 insert(size_type __pos1, const basic_string& __str, 564 size_type __pos2, size_type __n) 565 { 566 _Base::insert(__pos1, __str, __pos2, __n); 567 this->_M_invalidate_all(); 568 return *this; 569 } 570 571 basic_string& 572 insert(size_type __pos, const _CharT* __s, size_type __n) 573 { 574 __glibcxx_check_string(__s); 575 _Base::insert(__pos, __s, __n); 576 this->_M_invalidate_all(); 577 return *this; 578 } 579 580 basic_string& 581 insert(size_type __pos, const _CharT* __s) 582 { 583 __glibcxx_check_string(__s); 584 _Base::insert(__pos, __s); 585 this->_M_invalidate_all(); 586 return *this; 587 } 588 589 basic_string& 590 insert(size_type __pos, size_type __n, _CharT __c) 591 { 592 _Base::insert(__pos, __n, __c); 593 this->_M_invalidate_all(); 594 return *this; 595 } 596 597 iterator 598 insert(__const_iterator __p, _CharT __c) 599 { 600 __glibcxx_check_insert(__p); 601 typename _Base::iterator __res = _Base::insert(__p.base(), __c); 602 this->_M_invalidate_all(); 603 return iterator(__res, this); 604 } 605 606#if __cplusplus >= 201103L 607 iterator 608 insert(const_iterator __p, size_type __n, _CharT __c) 609 { 610 __glibcxx_check_insert(__p); 611#if _GLIBCXX_USE_CXX11_ABI 612 typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c); 613#else 614 const size_type __offset = __p.base() - _Base::cbegin(); 615 _Base::insert(_Base::begin() + __offset, __n, __c); 616 typename _Base::iterator __res = _Base::begin() + __offset; 617#endif 618 this->_M_invalidate_all(); 619 return iterator(__res, this); 620 } 621#else 622 void 623 insert(iterator __p, size_type __n, _CharT __c) 624 { 625 __glibcxx_check_insert(__p); 626 _Base::insert(__p.base(), __n, __c); 627 this->_M_invalidate_all(); 628 } 629#endif 630 631 template<typename _InputIterator> 632 iterator 633 insert(__const_iterator __p, 634 _InputIterator __first, _InputIterator __last) 635 { 636 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 637 __glibcxx_check_insert_range(__p, __first, __last, __dist); 638 639 typename _Base::iterator __res; 640#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR 641 const size_type __offset = __p.base() - _Base::begin(); 642#endif 643 if (__dist.second >= __dp_sign) 644 { 645 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =) 646 _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), 647 __gnu_debug::__unsafe(__last)); 648 } 649 else 650 { 651 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =) 652 _Base::insert(__p.base(), __first, __last); 653 } 654 655#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR 656 __res = _Base::begin() + __offset; 657#endif 658 this->_M_invalidate_all(); 659 return iterator(__res, this); 660 } 661 662#if __cplusplus >= 201103L 663 iterator 664 insert(const_iterator __p, std::initializer_list<_CharT> __l) 665 { 666 __glibcxx_check_insert(__p); 667#if _GLIBCXX_USE_CXX11_ABI 668 const auto __res = _Base::insert(__p.base(), __l); 669#else 670 const size_type __offset = __p.base() - _Base::cbegin(); 671 _Base::insert(_Base::begin() + __offset, __l); 672 auto __res = _Base::begin() + __offset; 673#endif 674 this->_M_invalidate_all(); 675 return iterator(__res, this); 676 } 677#endif // C++11 678 679 basic_string& 680 erase(size_type __pos = 0, size_type __n = _Base::npos) 681 { 682 _Base::erase(__pos, __n); 683 this->_M_invalidate_all(); 684 return *this; 685 } 686 687 iterator 688 erase(__const_iterator __position) 689 { 690 __glibcxx_check_erase(__position); 691 typename _Base::iterator __res = _Base::erase(__position.base()); 692 this->_M_invalidate_all(); 693 return iterator(__res, this); 694 } 695 696 iterator 697 erase(__const_iterator __first, __const_iterator __last) 698 { 699 // _GLIBCXX_RESOLVE_LIB_DEFECTS 700 // 151. can't currently clear() empty container 701 __glibcxx_check_erase_range(__first, __last); 702 typename _Base::iterator __res = _Base::erase(__first.base(), 703 __last.base()); 704 this->_M_invalidate_all(); 705 return iterator(__res, this); 706 } 707 708#if __cplusplus >= 201103L 709 void 710 pop_back() // noexcept 711 { 712 __glibcxx_check_nonempty(); 713 _Base::pop_back(); 714 this->_M_invalidate_all(); 715 } 716#endif // C++11 717 718 basic_string& 719 replace(size_type __pos1, size_type __n1, const basic_string& __str) 720 { 721 _Base::replace(__pos1, __n1, __str); 722 this->_M_invalidate_all(); 723 return *this; 724 } 725 726 basic_string& 727 replace(size_type __pos1, size_type __n1, const basic_string& __str, 728 size_type __pos2, size_type __n2) 729 { 730 _Base::replace(__pos1, __n1, __str, __pos2, __n2); 731 this->_M_invalidate_all(); 732 return *this; 733 } 734 735 basic_string& 736 replace(size_type __pos, size_type __n1, const _CharT* __s, 737 size_type __n2) 738 { 739 __glibcxx_check_string_len(__s, __n2); 740 _Base::replace(__pos, __n1, __s, __n2); 741 this->_M_invalidate_all(); 742 return *this; 743 } 744 745 basic_string& 746 replace(size_type __pos, size_type __n1, const _CharT* __s) 747 { 748 __glibcxx_check_string(__s); 749 _Base::replace(__pos, __n1, __s); 750 this->_M_invalidate_all(); 751 return *this; 752 } 753 754 basic_string& 755 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) 756 { 757 _Base::replace(__pos, __n1, __n2, __c); 758 this->_M_invalidate_all(); 759 return *this; 760 } 761 762 basic_string& 763 replace(__const_iterator __i1, __const_iterator __i2, 764 const basic_string& __str) 765 { 766 __glibcxx_check_erase_range(__i1, __i2); 767 _Base::replace(__i1.base(), __i2.base(), __str); 768 this->_M_invalidate_all(); 769 return *this; 770 } 771 772 basic_string& 773 replace(__const_iterator __i1, __const_iterator __i2, 774 const _CharT* __s, size_type __n) 775 { 776 __glibcxx_check_erase_range(__i1, __i2); 777 __glibcxx_check_string_len(__s, __n); 778 _Base::replace(__i1.base(), __i2.base(), __s, __n); 779 this->_M_invalidate_all(); 780 return *this; 781 } 782 783 basic_string& 784 replace(__const_iterator __i1, __const_iterator __i2, 785 const _CharT* __s) 786 { 787 __glibcxx_check_erase_range(__i1, __i2); 788 __glibcxx_check_string(__s); 789 _Base::replace(__i1.base(), __i2.base(), __s); 790 this->_M_invalidate_all(); 791 return *this; 792 } 793 794 basic_string& 795 replace(__const_iterator __i1, __const_iterator __i2, 796 size_type __n, _CharT __c) 797 { 798 __glibcxx_check_erase_range(__i1, __i2); 799 _Base::replace(__i1.base(), __i2.base(), __n, __c); 800 this->_M_invalidate_all(); 801 return *this; 802 } 803 804 template<typename _InputIterator> 805 basic_string& 806 replace(__const_iterator __i1, __const_iterator __i2, 807 _InputIterator __j1, _InputIterator __j2) 808 { 809 __glibcxx_check_erase_range(__i1, __i2); 810 811 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 812 __glibcxx_check_valid_range2(__j1, __j2, __dist); 813 814 if (__dist.second >= __dp_sign) 815 _Base::replace(__i1.base(), __i2.base(), 816 __gnu_debug::__unsafe(__j1), 817 __gnu_debug::__unsafe(__j2)); 818 else 819 _Base::replace(__i1.base(), __i2.base(), __j1, __j2); 820 821 this->_M_invalidate_all(); 822 return *this; 823 } 824 825#if __cplusplus >= 201103L 826 basic_string& 827 replace(__const_iterator __i1, __const_iterator __i2, 828 std::initializer_list<_CharT> __l) 829 { 830 __glibcxx_check_erase_range(__i1, __i2); 831 _Base::replace(__i1.base(), __i2.base(), __l); 832 this->_M_invalidate_all(); 833 return *this; 834 } 835#endif // C++11 836 837 size_type 838 copy(_CharT* __s, size_type __n, size_type __pos = 0) const 839 { 840 __glibcxx_check_string_len(__s, __n); 841 return _Base::copy(__s, __n, __pos); 842 } 843 844 void 845 swap(basic_string& __x) 846 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value) 847 { 848 _Safe::_M_swap(__x); 849 _Base::swap(__x); 850 } 851 852 // 21.3.6 string operations: 853 const _CharT* 854 c_str() const _GLIBCXX_NOEXCEPT 855 { 856 const _CharT* __res = _Base::c_str(); 857 this->_M_invalidate_all(); 858 return __res; 859 } 860 861 const _CharT* 862 data() const _GLIBCXX_NOEXCEPT 863 { 864 const _CharT* __res = _Base::data(); 865 this->_M_invalidate_all(); 866 return __res; 867 } 868 869 using _Base::get_allocator; 870 871 size_type 872 find(const basic_string& __str, size_type __pos = 0) const 873 _GLIBCXX_NOEXCEPT 874 { return _Base::find(__str, __pos); } 875 876 size_type 877 find(const _CharT* __s, size_type __pos, size_type __n) const 878 { 879 __glibcxx_check_string(__s); 880 return _Base::find(__s, __pos, __n); 881 } 882 883 size_type 884 find(const _CharT* __s, size_type __pos = 0) const 885 { 886 __glibcxx_check_string(__s); 887 return _Base::find(__s, __pos); 888 } 889 890 size_type 891 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 892 { return _Base::find(__c, __pos); } 893 894 size_type 895 rfind(const basic_string& __str, size_type __pos = _Base::npos) const 896 _GLIBCXX_NOEXCEPT 897 { return _Base::rfind(__str, __pos); } 898 899 size_type 900 rfind(const _CharT* __s, size_type __pos, size_type __n) const 901 { 902 __glibcxx_check_string_len(__s, __n); 903 return _Base::rfind(__s, __pos, __n); 904 } 905 906 size_type 907 rfind(const _CharT* __s, size_type __pos = _Base::npos) const 908 { 909 __glibcxx_check_string(__s); 910 return _Base::rfind(__s, __pos); 911 } 912 913 size_type 914 rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 915 { return _Base::rfind(__c, __pos); } 916 917 size_type 918 find_first_of(const basic_string& __str, size_type __pos = 0) const 919 _GLIBCXX_NOEXCEPT 920 { return _Base::find_first_of(__str, __pos); } 921 922 size_type 923 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 924 { 925 __glibcxx_check_string(__s); 926 return _Base::find_first_of(__s, __pos, __n); 927 } 928 929 size_type 930 find_first_of(const _CharT* __s, size_type __pos = 0) const 931 { 932 __glibcxx_check_string(__s); 933 return _Base::find_first_of(__s, __pos); 934 } 935 936 size_type 937 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 938 { return _Base::find_first_of(__c, __pos); } 939 940 size_type 941 find_last_of(const basic_string& __str, 942 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 943 { return _Base::find_last_of(__str, __pos); } 944 945 size_type 946 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 947 { 948 __glibcxx_check_string(__s); 949 return _Base::find_last_of(__s, __pos, __n); 950 } 951 952 size_type 953 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const 954 { 955 __glibcxx_check_string(__s); 956 return _Base::find_last_of(__s, __pos); 957 } 958 959 size_type 960 find_last_of(_CharT __c, size_type __pos = _Base::npos) const 961 _GLIBCXX_NOEXCEPT 962 { return _Base::find_last_of(__c, __pos); } 963 964 size_type 965 find_first_not_of(const basic_string& __str, size_type __pos = 0) const 966 _GLIBCXX_NOEXCEPT 967 { return _Base::find_first_not_of(__str, __pos); } 968 969 size_type 970 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 971 { 972 __glibcxx_check_string_len(__s, __n); 973 return _Base::find_first_not_of(__s, __pos, __n); 974 } 975 976 size_type 977 find_first_not_of(const _CharT* __s, size_type __pos = 0) const 978 { 979 __glibcxx_check_string(__s); 980 return _Base::find_first_not_of(__s, __pos); 981 } 982 983 size_type 984 find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 985 { return _Base::find_first_not_of(__c, __pos); } 986 987 size_type 988 find_last_not_of(const basic_string& __str, 989 size_type __pos = _Base::npos) const 990 _GLIBCXX_NOEXCEPT 991 { return _Base::find_last_not_of(__str, __pos); } 992 993 size_type 994 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 995 { 996 __glibcxx_check_string(__s); 997 return _Base::find_last_not_of(__s, __pos, __n); 998 } 999 1000 size_type 1001 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const 1002 { 1003 __glibcxx_check_string(__s); 1004 return _Base::find_last_not_of(__s, __pos); 1005 } 1006 1007 size_type 1008 find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const 1009 _GLIBCXX_NOEXCEPT 1010 { return _Base::find_last_not_of(__c, __pos); } 1011 1012 basic_string 1013 substr(size_type __pos = 0, size_type __n = _Base::npos) const 1014 { return basic_string(_Base::substr(__pos, __n)); } 1015 1016 int 1017 compare(const basic_string& __str) const 1018 { return _Base::compare(__str); } 1019 1020 int 1021 compare(size_type __pos1, size_type __n1, 1022 const basic_string& __str) const 1023 { return _Base::compare(__pos1, __n1, __str); } 1024 1025 int 1026 compare(size_type __pos1, size_type __n1, const basic_string& __str, 1027 size_type __pos2, size_type __n2) const 1028 { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } 1029 1030 int 1031 compare(const _CharT* __s) const 1032 { 1033 __glibcxx_check_string(__s); 1034 return _Base::compare(__s); 1035 } 1036 1037 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1038 // 5. string::compare specification questionable 1039 int 1040 compare(size_type __pos1, size_type __n1, const _CharT* __s) const 1041 { 1042 __glibcxx_check_string(__s); 1043 return _Base::compare(__pos1, __n1, __s); 1044 } 1045 1046 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1047 // 5. string::compare specification questionable 1048 int 1049 compare(size_type __pos1, size_type __n1,const _CharT* __s, 1050 size_type __n2) const 1051 { 1052 __glibcxx_check_string_len(__s, __n2); 1053 return _Base::compare(__pos1, __n1, __s, __n2); 1054 } 1055 1056 _Base& 1057 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 1058 1059 const _Base& 1060 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 1061 1062 using _Safe::_M_invalidate_all; 1063 }; 1064 1065 template<typename _CharT, typename _Traits, typename _Allocator> 1066 inline basic_string<_CharT,_Traits,_Allocator> 1067 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1068 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1069 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 1070 1071 template<typename _CharT, typename _Traits, typename _Allocator> 1072 inline basic_string<_CharT,_Traits,_Allocator> 1073 operator+(const _CharT* __lhs, 1074 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1075 { 1076 __glibcxx_check_string(__lhs); 1077 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 1078 } 1079 1080 template<typename _CharT, typename _Traits, typename _Allocator> 1081 inline basic_string<_CharT,_Traits,_Allocator> 1082 operator+(_CharT __lhs, 1083 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1084 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } 1085 1086 template<typename _CharT, typename _Traits, typename _Allocator> 1087 inline basic_string<_CharT,_Traits,_Allocator> 1088 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1089 const _CharT* __rhs) 1090 { 1091 __glibcxx_check_string(__rhs); 1092 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 1093 } 1094 1095 template<typename _CharT, typename _Traits, typename _Allocator> 1096 inline basic_string<_CharT,_Traits,_Allocator> 1097 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1098 _CharT __rhs) 1099 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 1100 1101 template<typename _CharT, typename _Traits, typename _Allocator> 1102 inline bool 1103 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1104 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1105 { return __lhs._M_base() == __rhs._M_base(); } 1106 1107 template<typename _CharT, typename _Traits, typename _Allocator> 1108 inline bool 1109 operator==(const _CharT* __lhs, 1110 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1111 { 1112 __glibcxx_check_string(__lhs); 1113 return __lhs == __rhs._M_base(); 1114 } 1115 1116 template<typename _CharT, typename _Traits, typename _Allocator> 1117 inline bool 1118 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1119 const _CharT* __rhs) 1120 { 1121 __glibcxx_check_string(__rhs); 1122 return __lhs._M_base() == __rhs; 1123 } 1124 1125 template<typename _CharT, typename _Traits, typename _Allocator> 1126 inline bool 1127 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1128 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1129 { return __lhs._M_base() != __rhs._M_base(); } 1130 1131 template<typename _CharT, typename _Traits, typename _Allocator> 1132 inline bool 1133 operator!=(const _CharT* __lhs, 1134 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1135 { 1136 __glibcxx_check_string(__lhs); 1137 return __lhs != __rhs._M_base(); 1138 } 1139 1140 template<typename _CharT, typename _Traits, typename _Allocator> 1141 inline bool 1142 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1143 const _CharT* __rhs) 1144 { 1145 __glibcxx_check_string(__rhs); 1146 return __lhs._M_base() != __rhs; 1147 } 1148 1149 template<typename _CharT, typename _Traits, typename _Allocator> 1150 inline bool 1151 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1152 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1153 { return __lhs._M_base() < __rhs._M_base(); } 1154 1155 template<typename _CharT, typename _Traits, typename _Allocator> 1156 inline bool 1157 operator<(const _CharT* __lhs, 1158 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1159 { 1160 __glibcxx_check_string(__lhs); 1161 return __lhs < __rhs._M_base(); 1162 } 1163 1164 template<typename _CharT, typename _Traits, typename _Allocator> 1165 inline bool 1166 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1167 const _CharT* __rhs) 1168 { 1169 __glibcxx_check_string(__rhs); 1170 return __lhs._M_base() < __rhs; 1171 } 1172 1173 template<typename _CharT, typename _Traits, typename _Allocator> 1174 inline bool 1175 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1176 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1177 { return __lhs._M_base() <= __rhs._M_base(); } 1178 1179 template<typename _CharT, typename _Traits, typename _Allocator> 1180 inline bool 1181 operator<=(const _CharT* __lhs, 1182 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1183 { 1184 __glibcxx_check_string(__lhs); 1185 return __lhs <= __rhs._M_base(); 1186 } 1187 1188 template<typename _CharT, typename _Traits, typename _Allocator> 1189 inline bool 1190 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1191 const _CharT* __rhs) 1192 { 1193 __glibcxx_check_string(__rhs); 1194 return __lhs._M_base() <= __rhs; 1195 } 1196 1197 template<typename _CharT, typename _Traits, typename _Allocator> 1198 inline bool 1199 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1200 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1201 { return __lhs._M_base() >= __rhs._M_base(); } 1202 1203 template<typename _CharT, typename _Traits, typename _Allocator> 1204 inline bool 1205 operator>=(const _CharT* __lhs, 1206 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1207 { 1208 __glibcxx_check_string(__lhs); 1209 return __lhs >= __rhs._M_base(); 1210 } 1211 1212 template<typename _CharT, typename _Traits, typename _Allocator> 1213 inline bool 1214 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1215 const _CharT* __rhs) 1216 { 1217 __glibcxx_check_string(__rhs); 1218 return __lhs._M_base() >= __rhs; 1219 } 1220 1221 template<typename _CharT, typename _Traits, typename _Allocator> 1222 inline bool 1223 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1224 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1225 { return __lhs._M_base() > __rhs._M_base(); } 1226 1227 template<typename _CharT, typename _Traits, typename _Allocator> 1228 inline bool 1229 operator>(const _CharT* __lhs, 1230 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1231 { 1232 __glibcxx_check_string(__lhs); 1233 return __lhs > __rhs._M_base(); 1234 } 1235 1236 template<typename _CharT, typename _Traits, typename _Allocator> 1237 inline bool 1238 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1239 const _CharT* __rhs) 1240 { 1241 __glibcxx_check_string(__rhs); 1242 return __lhs._M_base() > __rhs; 1243 } 1244 1245 // 21.3.7.8: 1246 template<typename _CharT, typename _Traits, typename _Allocator> 1247 inline void 1248 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, 1249 basic_string<_CharT,_Traits,_Allocator>& __rhs) 1250 { __lhs.swap(__rhs); } 1251 1252 template<typename _CharT, typename _Traits, typename _Allocator> 1253 std::basic_ostream<_CharT, _Traits>& 1254 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1255 const basic_string<_CharT, _Traits, _Allocator>& __str) 1256 { return __os << __str._M_base(); } 1257 1258 template<typename _CharT, typename _Traits, typename _Allocator> 1259 std::basic_istream<_CharT,_Traits>& 1260 operator>>(std::basic_istream<_CharT,_Traits>& __is, 1261 basic_string<_CharT,_Traits,_Allocator>& __str) 1262 { 1263 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); 1264 __str._M_invalidate_all(); 1265 return __res; 1266 } 1267 1268 template<typename _CharT, typename _Traits, typename _Allocator> 1269 std::basic_istream<_CharT,_Traits>& 1270 getline(std::basic_istream<_CharT,_Traits>& __is, 1271 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) 1272 { 1273 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 1274 __str._M_base(), 1275 __delim); 1276 __str._M_invalidate_all(); 1277 return __res; 1278 } 1279 1280 template<typename _CharT, typename _Traits, typename _Allocator> 1281 std::basic_istream<_CharT,_Traits>& 1282 getline(std::basic_istream<_CharT,_Traits>& __is, 1283 basic_string<_CharT,_Traits,_Allocator>& __str) 1284 { 1285 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 1286 __str._M_base()); 1287 __str._M_invalidate_all(); 1288 return __res; 1289 } 1290 1291 typedef basic_string<char> string; 1292 1293 typedef basic_string<wchar_t> wstring; 1294 1295#ifdef _GLIBCXX_USE_CHAR8_T 1296 /// A string of @c char8_t 1297 typedef basic_string<char8_t> u8string; 1298#endif 1299 1300#if __cplusplus >= 201103L 1301 /// A string of @c char16_t 1302 typedef basic_string<char16_t> u16string; 1303 1304 /// A string of @c char32_t 1305 typedef basic_string<char32_t> u32string; 1306#endif 1307 1308 template<typename _CharT, typename _Traits, typename _Allocator> 1309 struct _Insert_range_from_self_is_safe< 1310 __gnu_debug::basic_string<_CharT, _Traits, _Allocator> > 1311 { enum { __value = 1 }; }; 1312 1313} // namespace __gnu_debug 1314 1315#if __cplusplus >= 201103L 1316namespace std _GLIBCXX_VISIBILITY(default) 1317{ 1318_GLIBCXX_BEGIN_NAMESPACE_VERSION 1319 1320 /// std::hash specialization for __gnu_debug::basic_string. 1321 template<typename _CharT> 1322 struct hash<__gnu_debug::basic_string<_CharT>> 1323 : public hash<std::basic_string<_CharT>> 1324 { }; 1325 1326 template<typename _CharT> 1327 struct __is_fast_hash<hash<__gnu_debug::basic_string<_CharT>>> 1328 : __is_fast_hash<hash<std::basic_string<_CharT>>> 1329 { }; 1330 1331_GLIBCXX_END_NAMESPACE_VERSION 1332} 1333#endif /* C++11 */ 1334 1335#undef _GLIBCXX_INSERT_RETURNS_ITERATOR 1336#undef _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY 1337 1338#endif 1339