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