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