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