1 // Debugging string implementation -*- C++ -*- 2 3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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) { } 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()) 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) noexcept 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() _GLIBCXX_NOEXCEPT { } 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() _GLIBCXX_NOEXCEPT 175 { return iterator(_Base::begin(), this); } 176 177 const_iterator 178 begin() const _GLIBCXX_NOEXCEPT 179 { return const_iterator(_Base::begin(), this); } 180 181 iterator 182 end() _GLIBCXX_NOEXCEPT 183 { return iterator(_Base::end(), this); } 184 185 const_iterator 186 end() const _GLIBCXX_NOEXCEPT 187 { return const_iterator(_Base::end(), this); } 188 189 reverse_iterator 190 rbegin() _GLIBCXX_NOEXCEPT 191 { return reverse_iterator(end()); } 192 193 const_reverse_iterator 194 rbegin() const _GLIBCXX_NOEXCEPT 195 { return const_reverse_iterator(end()); } 196 197 reverse_iterator 198 rend() _GLIBCXX_NOEXCEPT 199 { return reverse_iterator(begin()); } 200 201 const_reverse_iterator 202 rend() const _GLIBCXX_NOEXCEPT 203 { return const_reverse_iterator(begin()); } 204 205 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 206 const_iterator 207 cbegin() const noexcept 208 { return const_iterator(_Base::begin(), this); } 209 210 const_iterator 211 cend() const noexcept 212 { return const_iterator(_Base::end(), this); } 213 214 const_reverse_iterator 215 crbegin() const noexcept 216 { return const_reverse_iterator(end()); } 217 218 const_reverse_iterator 219 crend() const noexcept 220 { return const_reverse_iterator(begin()); } 221 #endif 222 223 // 21.3.3 capacity: 224 using _Base::size; 225 using _Base::length; 226 using _Base::max_size; 227 228 void 229 resize(size_type __n, _CharT __c) 230 { 231 _Base::resize(__n, __c); 232 this->_M_invalidate_all(); 233 } 234 235 void 236 resize(size_type __n) 237 { this->resize(__n, _CharT()); } 238 239 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 240 void 241 shrink_to_fit() 242 { 243 if (capacity() > size()) 244 { 245 __try 246 { 247 reserve(0); 248 this->_M_invalidate_all(); 249 } 250 __catch(...) 251 { } 252 } 253 } 254 #endif 255 256 using _Base::capacity; 257 using _Base::reserve; 258 259 void 260 clear() _GLIBCXX_NOEXCEPT 261 { 262 _Base::clear(); 263 this->_M_invalidate_all(); 264 } 265 266 using _Base::empty; 267 268 // 21.3.4 element access: 269 const_reference 270 operator[](size_type __pos) const 271 { 272 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 273 _M_message(__gnu_debug::__msg_subscript_oob) 274 ._M_sequence(*this, "this") 275 ._M_integer(__pos, "__pos") 276 ._M_integer(this->size(), "size")); 277 return _M_base()[__pos]; 278 } 279 280 reference 281 operator[](size_type __pos) 282 { 283 #ifdef _GLIBCXX_DEBUG_PEDANTIC 284 __glibcxx_check_subscript(__pos); 285 #else 286 // as an extension v3 allows s[s.size()] when s is non-const. 287 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), 288 _M_message(__gnu_debug::__msg_subscript_oob) 289 ._M_sequence(*this, "this") 290 ._M_integer(__pos, "__pos") 291 ._M_integer(this->size(), "size")); 292 #endif 293 return _M_base()[__pos]; 294 } 295 296 using _Base::at; 297 298 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 299 using _Base::front; 300 using _Base::back; 301 #endif 302 303 // 21.3.5 modifiers: 304 basic_string& 305 operator+=(const basic_string& __str) 306 { 307 _M_base() += __str; 308 this->_M_invalidate_all(); 309 return *this; 310 } 311 312 basic_string& 313 operator+=(const _CharT* __s) 314 { 315 __glibcxx_check_string(__s); 316 _M_base() += __s; 317 this->_M_invalidate_all(); 318 return *this; 319 } 320 321 basic_string& 322 operator+=(_CharT __c) 323 { 324 _M_base() += __c; 325 this->_M_invalidate_all(); 326 return *this; 327 } 328 329 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 330 basic_string& 331 operator+=(std::initializer_list<_CharT> __l) 332 { 333 _M_base() += __l; 334 this->_M_invalidate_all(); 335 return *this; 336 } 337 #endif // __GXX_EXPERIMENTAL_CXX0X__ 338 339 basic_string& 340 append(const basic_string& __str) 341 { 342 _Base::append(__str); 343 this->_M_invalidate_all(); 344 return *this; 345 } 346 347 basic_string& 348 append(const basic_string& __str, size_type __pos, size_type __n) 349 { 350 _Base::append(__str, __pos, __n); 351 this->_M_invalidate_all(); 352 return *this; 353 } 354 355 basic_string& 356 append(const _CharT* __s, size_type __n) 357 { 358 __glibcxx_check_string_len(__s, __n); 359 _Base::append(__s, __n); 360 this->_M_invalidate_all(); 361 return *this; 362 } 363 364 basic_string& 365 append(const _CharT* __s) 366 { 367 __glibcxx_check_string(__s); 368 _Base::append(__s); 369 this->_M_invalidate_all(); 370 return *this; 371 } 372 373 basic_string& 374 append(size_type __n, _CharT __c) 375 { 376 _Base::append(__n, __c); 377 this->_M_invalidate_all(); 378 return *this; 379 } 380 381 template<typename _InputIterator> 382 basic_string& 383 append(_InputIterator __first, _InputIterator __last) 384 { 385 __glibcxx_check_valid_range(__first, __last); 386 _Base::append(__gnu_debug::__base(__first), 387 __gnu_debug::__base(__last)); 388 this->_M_invalidate_all(); 389 return *this; 390 } 391 392 // _GLIBCXX_RESOLVE_LIB_DEFECTS 393 // 7. string clause minor problems 394 void 395 push_back(_CharT __c) 396 { 397 _Base::push_back(__c); 398 this->_M_invalidate_all(); 399 } 400 401 basic_string& 402 assign(const basic_string& __x) 403 { 404 _Base::assign(__x); 405 this->_M_invalidate_all(); 406 return *this; 407 } 408 409 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 410 basic_string& 411 assign(basic_string&& __x) 412 { 413 _Base::assign(std::move(__x)); 414 this->_M_invalidate_all(); 415 return *this; 416 } 417 #endif // __GXX_EXPERIMENTAL_CXX0X__ 418 419 basic_string& 420 assign(const basic_string& __str, size_type __pos, size_type __n) 421 { 422 _Base::assign(__str, __pos, __n); 423 this->_M_invalidate_all(); 424 return *this; 425 } 426 427 basic_string& 428 assign(const _CharT* __s, size_type __n) 429 { 430 __glibcxx_check_string_len(__s, __n); 431 _Base::assign(__s, __n); 432 this->_M_invalidate_all(); 433 return *this; 434 } 435 436 basic_string& 437 assign(const _CharT* __s) 438 { 439 __glibcxx_check_string(__s); 440 _Base::assign(__s); 441 this->_M_invalidate_all(); 442 return *this; 443 } 444 445 basic_string& 446 assign(size_type __n, _CharT __c) 447 { 448 _Base::assign(__n, __c); 449 this->_M_invalidate_all(); 450 return *this; 451 } 452 453 template<typename _InputIterator> 454 basic_string& 455 assign(_InputIterator __first, _InputIterator __last) 456 { 457 __glibcxx_check_valid_range(__first, __last); 458 _Base::assign(__gnu_debug::__base(__first), 459 __gnu_debug::__base(__last)); 460 this->_M_invalidate_all(); 461 return *this; 462 } 463 464 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 465 basic_string& 466 assign(std::initializer_list<_CharT> __l) 467 { 468 _Base::assign(__l); 469 this->_M_invalidate_all(); 470 return *this; 471 } 472 #endif // __GXX_EXPERIMENTAL_CXX0X__ 473 474 basic_string& 475 insert(size_type __pos1, const basic_string& __str) 476 { 477 _Base::insert(__pos1, __str); 478 this->_M_invalidate_all(); 479 return *this; 480 } 481 482 basic_string& 483 insert(size_type __pos1, const basic_string& __str, 484 size_type __pos2, size_type __n) 485 { 486 _Base::insert(__pos1, __str, __pos2, __n); 487 this->_M_invalidate_all(); 488 return *this; 489 } 490 491 basic_string& 492 insert(size_type __pos, const _CharT* __s, size_type __n) 493 { 494 __glibcxx_check_string(__s); 495 _Base::insert(__pos, __s, __n); 496 this->_M_invalidate_all(); 497 return *this; 498 } 499 500 basic_string& 501 insert(size_type __pos, const _CharT* __s) 502 { 503 __glibcxx_check_string(__s); 504 _Base::insert(__pos, __s); 505 this->_M_invalidate_all(); 506 return *this; 507 } 508 509 basic_string& 510 insert(size_type __pos, size_type __n, _CharT __c) 511 { 512 _Base::insert(__pos, __n, __c); 513 this->_M_invalidate_all(); 514 return *this; 515 } 516 517 iterator 518 insert(iterator __p, _CharT __c) 519 { 520 __glibcxx_check_insert(__p); 521 typename _Base::iterator __res = _Base::insert(__p.base(), __c); 522 this->_M_invalidate_all(); 523 return iterator(__res, this); 524 } 525 526 void 527 insert(iterator __p, size_type __n, _CharT __c) 528 { 529 __glibcxx_check_insert(__p); 530 _Base::insert(__p.base(), __n, __c); 531 this->_M_invalidate_all(); 532 } 533 534 template<typename _InputIterator> 535 void 536 insert(iterator __p, _InputIterator __first, _InputIterator __last) 537 { 538 __glibcxx_check_insert_range(__p, __first, __last); 539 _Base::insert(__p.base(), __gnu_debug::__base(__first), 540 __gnu_debug::__base(__last)); 541 this->_M_invalidate_all(); 542 } 543 544 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 545 void 546 insert(iterator __p, std::initializer_list<_CharT> __l) 547 { 548 __glibcxx_check_insert(__p); 549 _Base::insert(__p.base(), __l); 550 this->_M_invalidate_all(); 551 } 552 #endif // __GXX_EXPERIMENTAL_CXX0X__ 553 554 basic_string& 555 erase(size_type __pos = 0, size_type __n = _Base::npos) 556 { 557 _Base::erase(__pos, __n); 558 this->_M_invalidate_all(); 559 return *this; 560 } 561 562 iterator 563 erase(iterator __position) 564 { 565 __glibcxx_check_erase(__position); 566 typename _Base::iterator __res = _Base::erase(__position.base()); 567 this->_M_invalidate_all(); 568 return iterator(__res, this); 569 } 570 571 iterator 572 erase(iterator __first, iterator __last) 573 { 574 // _GLIBCXX_RESOLVE_LIB_DEFECTS 575 // 151. can't currently clear() empty container 576 __glibcxx_check_erase_range(__first, __last); 577 typename _Base::iterator __res = _Base::erase(__first.base(), 578 __last.base()); 579 this->_M_invalidate_all(); 580 return iterator(__res, this); 581 } 582 583 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 584 void 585 pop_back() 586 { 587 __glibcxx_check_nonempty(); 588 _Base::pop_back(); 589 this->_M_invalidate_all(); 590 } 591 #endif // __GXX_EXPERIMENTAL_CXX0X__ 592 593 basic_string& 594 replace(size_type __pos1, size_type __n1, const basic_string& __str) 595 { 596 _Base::replace(__pos1, __n1, __str); 597 this->_M_invalidate_all(); 598 return *this; 599 } 600 601 basic_string& 602 replace(size_type __pos1, size_type __n1, const basic_string& __str, 603 size_type __pos2, size_type __n2) 604 { 605 _Base::replace(__pos1, __n1, __str, __pos2, __n2); 606 this->_M_invalidate_all(); 607 return *this; 608 } 609 610 basic_string& 611 replace(size_type __pos, size_type __n1, const _CharT* __s, 612 size_type __n2) 613 { 614 __glibcxx_check_string_len(__s, __n2); 615 _Base::replace(__pos, __n1, __s, __n2); 616 this->_M_invalidate_all(); 617 return *this; 618 } 619 620 basic_string& 621 replace(size_type __pos, size_type __n1, const _CharT* __s) 622 { 623 __glibcxx_check_string(__s); 624 _Base::replace(__pos, __n1, __s); 625 this->_M_invalidate_all(); 626 return *this; 627 } 628 629 basic_string& 630 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) 631 { 632 _Base::replace(__pos, __n1, __n2, __c); 633 this->_M_invalidate_all(); 634 return *this; 635 } 636 637 basic_string& 638 replace(iterator __i1, iterator __i2, const basic_string& __str) 639 { 640 __glibcxx_check_erase_range(__i1, __i2); 641 _Base::replace(__i1.base(), __i2.base(), __str); 642 this->_M_invalidate_all(); 643 return *this; 644 } 645 646 basic_string& 647 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) 648 { 649 __glibcxx_check_erase_range(__i1, __i2); 650 __glibcxx_check_string_len(__s, __n); 651 _Base::replace(__i1.base(), __i2.base(), __s, __n); 652 this->_M_invalidate_all(); 653 return *this; 654 } 655 656 basic_string& 657 replace(iterator __i1, iterator __i2, const _CharT* __s) 658 { 659 __glibcxx_check_erase_range(__i1, __i2); 660 __glibcxx_check_string(__s); 661 _Base::replace(__i1.base(), __i2.base(), __s); 662 this->_M_invalidate_all(); 663 return *this; 664 } 665 666 basic_string& 667 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) 668 { 669 __glibcxx_check_erase_range(__i1, __i2); 670 _Base::replace(__i1.base(), __i2.base(), __n, __c); 671 this->_M_invalidate_all(); 672 return *this; 673 } 674 675 template<typename _InputIterator> 676 basic_string& 677 replace(iterator __i1, iterator __i2, 678 _InputIterator __j1, _InputIterator __j2) 679 { 680 __glibcxx_check_erase_range(__i1, __i2); 681 __glibcxx_check_valid_range(__j1, __j2); 682 _Base::replace(__i1.base(), __i2.base(), __j1, __j2); 683 this->_M_invalidate_all(); 684 return *this; 685 } 686 687 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 688 basic_string& replace(iterator __i1, iterator __i2, 689 std::initializer_list<_CharT> __l) 690 { 691 __glibcxx_check_erase_range(__i1, __i2); 692 _Base::replace(__i1.base(), __i2.base(), __l); 693 this->_M_invalidate_all(); 694 return *this; 695 } 696 #endif // __GXX_EXPERIMENTAL_CXX0X__ 697 698 size_type 699 copy(_CharT* __s, size_type __n, size_type __pos = 0) const 700 { 701 __glibcxx_check_string_len(__s, __n); 702 return _Base::copy(__s, __n, __pos); 703 } 704 705 void 706 swap(basic_string<_CharT,_Traits,_Allocator>& __x) 707 { 708 _Base::swap(__x); 709 this->_M_swap(__x); 710 this->_M_invalidate_all(); 711 __x._M_invalidate_all(); 712 } 713 714 // 21.3.6 string operations: 715 const _CharT* 716 c_str() const _GLIBCXX_NOEXCEPT 717 { 718 const _CharT* __res = _Base::c_str(); 719 this->_M_invalidate_all(); 720 return __res; 721 } 722 723 const _CharT* 724 data() const _GLIBCXX_NOEXCEPT 725 { 726 const _CharT* __res = _Base::data(); 727 this->_M_invalidate_all(); 728 return __res; 729 } 730 731 using _Base::get_allocator; 732 733 size_type 734 find(const basic_string& __str, size_type __pos = 0) const 735 _GLIBCXX_NOEXCEPT 736 { return _Base::find(__str, __pos); } 737 738 size_type 739 find(const _CharT* __s, size_type __pos, size_type __n) const 740 { 741 __glibcxx_check_string(__s); 742 return _Base::find(__s, __pos, __n); 743 } 744 745 size_type 746 find(const _CharT* __s, size_type __pos = 0) const 747 { 748 __glibcxx_check_string(__s); 749 return _Base::find(__s, __pos); 750 } 751 752 size_type 753 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 754 { return _Base::find(__c, __pos); } 755 756 size_type 757 rfind(const basic_string& __str, size_type __pos = _Base::npos) const 758 _GLIBCXX_NOEXCEPT 759 { return _Base::rfind(__str, __pos); } 760 761 size_type 762 rfind(const _CharT* __s, size_type __pos, size_type __n) const 763 { 764 __glibcxx_check_string_len(__s, __n); 765 return _Base::rfind(__s, __pos, __n); 766 } 767 768 size_type 769 rfind(const _CharT* __s, size_type __pos = _Base::npos) const 770 { 771 __glibcxx_check_string(__s); 772 return _Base::rfind(__s, __pos); 773 } 774 775 size_type 776 rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 777 { return _Base::rfind(__c, __pos); } 778 779 size_type 780 find_first_of(const basic_string& __str, size_type __pos = 0) const 781 _GLIBCXX_NOEXCEPT 782 { return _Base::find_first_of(__str, __pos); } 783 784 size_type 785 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 786 { 787 __glibcxx_check_string(__s); 788 return _Base::find_first_of(__s, __pos, __n); 789 } 790 791 size_type 792 find_first_of(const _CharT* __s, size_type __pos = 0) const 793 { 794 __glibcxx_check_string(__s); 795 return _Base::find_first_of(__s, __pos); 796 } 797 798 size_type 799 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 800 { return _Base::find_first_of(__c, __pos); } 801 802 size_type 803 find_last_of(const basic_string& __str, 804 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT 805 { return _Base::find_last_of(__str, __pos); } 806 807 size_type 808 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 809 { 810 __glibcxx_check_string(__s); 811 return _Base::find_last_of(__s, __pos, __n); 812 } 813 814 size_type 815 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const 816 { 817 __glibcxx_check_string(__s); 818 return _Base::find_last_of(__s, __pos); 819 } 820 821 size_type 822 find_last_of(_CharT __c, size_type __pos = _Base::npos) const 823 _GLIBCXX_NOEXCEPT 824 { return _Base::find_last_of(__c, __pos); } 825 826 size_type 827 find_first_not_of(const basic_string& __str, size_type __pos = 0) const 828 _GLIBCXX_NOEXCEPT 829 { return _Base::find_first_not_of(__str, __pos); } 830 831 size_type 832 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 833 { 834 __glibcxx_check_string_len(__s, __n); 835 return _Base::find_first_not_of(__s, __pos, __n); 836 } 837 838 size_type 839 find_first_not_of(const _CharT* __s, size_type __pos = 0) const 840 { 841 __glibcxx_check_string(__s); 842 return _Base::find_first_not_of(__s, __pos); 843 } 844 845 size_type 846 find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT 847 { return _Base::find_first_not_of(__c, __pos); } 848 849 size_type 850 find_last_not_of(const basic_string& __str, 851 size_type __pos = _Base::npos) const 852 _GLIBCXX_NOEXCEPT 853 { return _Base::find_last_not_of(__str, __pos); } 854 855 size_type 856 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 857 { 858 __glibcxx_check_string(__s); 859 return _Base::find_last_not_of(__s, __pos, __n); 860 } 861 862 size_type 863 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const 864 { 865 __glibcxx_check_string(__s); 866 return _Base::find_last_not_of(__s, __pos); 867 } 868 869 size_type 870 find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const 871 _GLIBCXX_NOEXCEPT 872 { return _Base::find_last_not_of(__c, __pos); } 873 874 basic_string 875 substr(size_type __pos = 0, size_type __n = _Base::npos) const 876 { return basic_string(_Base::substr(__pos, __n)); } 877 878 int 879 compare(const basic_string& __str) const 880 { return _Base::compare(__str); } 881 882 int 883 compare(size_type __pos1, size_type __n1, 884 const basic_string& __str) const 885 { return _Base::compare(__pos1, __n1, __str); } 886 887 int 888 compare(size_type __pos1, size_type __n1, const basic_string& __str, 889 size_type __pos2, size_type __n2) const 890 { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } 891 892 int 893 compare(const _CharT* __s) const 894 { 895 __glibcxx_check_string(__s); 896 return _Base::compare(__s); 897 } 898 899 // _GLIBCXX_RESOLVE_LIB_DEFECTS 900 // 5. string::compare specification questionable 901 int 902 compare(size_type __pos1, size_type __n1, const _CharT* __s) const 903 { 904 __glibcxx_check_string(__s); 905 return _Base::compare(__pos1, __n1, __s); 906 } 907 908 // _GLIBCXX_RESOLVE_LIB_DEFECTS 909 // 5. string::compare specification questionable 910 int 911 compare(size_type __pos1, size_type __n1,const _CharT* __s, 912 size_type __n2) const 913 { 914 __glibcxx_check_string_len(__s, __n2); 915 return _Base::compare(__pos1, __n1, __s, __n2); 916 } 917 918 _Base& 919 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 920 921 const _Base& 922 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 923 924 using _Safe_base::_M_invalidate_all; 925 }; 926 927 template<typename _CharT, typename _Traits, typename _Allocator> 928 inline basic_string<_CharT,_Traits,_Allocator> 929 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 930 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 931 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 932 933 template<typename _CharT, typename _Traits, typename _Allocator> 934 inline basic_string<_CharT,_Traits,_Allocator> 935 operator+(const _CharT* __lhs, 936 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 937 { 938 __glibcxx_check_string(__lhs); 939 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 940 } 941 942 template<typename _CharT, typename _Traits, typename _Allocator> 943 inline basic_string<_CharT,_Traits,_Allocator> 944 operator+(_CharT __lhs, 945 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 946 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } 947 948 template<typename _CharT, typename _Traits, typename _Allocator> 949 inline basic_string<_CharT,_Traits,_Allocator> 950 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 951 const _CharT* __rhs) 952 { 953 __glibcxx_check_string(__rhs); 954 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 955 } 956 957 template<typename _CharT, typename _Traits, typename _Allocator> 958 inline basic_string<_CharT,_Traits,_Allocator> 959 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 960 _CharT __rhs) 961 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } 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 template<typename _CharT, typename _Traits, typename _Allocator> 1060 inline bool 1061 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1062 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1063 { return __lhs._M_base() >= __rhs._M_base(); } 1064 1065 template<typename _CharT, typename _Traits, typename _Allocator> 1066 inline bool 1067 operator>=(const _CharT* __lhs, 1068 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1069 { 1070 __glibcxx_check_string(__lhs); 1071 return __lhs >= __rhs._M_base(); 1072 } 1073 1074 template<typename _CharT, typename _Traits, typename _Allocator> 1075 inline bool 1076 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1077 const _CharT* __rhs) 1078 { 1079 __glibcxx_check_string(__rhs); 1080 return __lhs._M_base() >= __rhs; 1081 } 1082 1083 template<typename _CharT, typename _Traits, typename _Allocator> 1084 inline bool 1085 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1086 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1087 { return __lhs._M_base() > __rhs._M_base(); } 1088 1089 template<typename _CharT, typename _Traits, typename _Allocator> 1090 inline bool 1091 operator>(const _CharT* __lhs, 1092 const basic_string<_CharT,_Traits,_Allocator>& __rhs) 1093 { 1094 __glibcxx_check_string(__lhs); 1095 return __lhs > __rhs._M_base(); 1096 } 1097 1098 template<typename _CharT, typename _Traits, typename _Allocator> 1099 inline bool 1100 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 1101 const _CharT* __rhs) 1102 { 1103 __glibcxx_check_string(__rhs); 1104 return __lhs._M_base() > __rhs; 1105 } 1106 1107 // 21.3.7.8: 1108 template<typename _CharT, typename _Traits, typename _Allocator> 1109 inline void 1110 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, 1111 basic_string<_CharT,_Traits,_Allocator>& __rhs) 1112 { __lhs.swap(__rhs); } 1113 1114 template<typename _CharT, typename _Traits, typename _Allocator> 1115 std::basic_ostream<_CharT, _Traits>& 1116 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1117 const basic_string<_CharT, _Traits, _Allocator>& __str) 1118 { return __os << __str._M_base(); } 1119 1120 template<typename _CharT, typename _Traits, typename _Allocator> 1121 std::basic_istream<_CharT,_Traits>& 1122 operator>>(std::basic_istream<_CharT,_Traits>& __is, 1123 basic_string<_CharT,_Traits,_Allocator>& __str) 1124 { 1125 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); 1126 __str._M_invalidate_all(); 1127 return __res; 1128 } 1129 1130 template<typename _CharT, typename _Traits, typename _Allocator> 1131 std::basic_istream<_CharT,_Traits>& 1132 getline(std::basic_istream<_CharT,_Traits>& __is, 1133 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) 1134 { 1135 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 1136 __str._M_base(), 1137 __delim); 1138 __str._M_invalidate_all(); 1139 return __res; 1140 } 1141 1142 template<typename _CharT, typename _Traits, typename _Allocator> 1143 std::basic_istream<_CharT,_Traits>& 1144 getline(std::basic_istream<_CharT,_Traits>& __is, 1145 basic_string<_CharT,_Traits,_Allocator>& __str) 1146 { 1147 std::basic_istream<_CharT,_Traits>& __res = getline(__is, 1148 __str._M_base()); 1149 __str._M_invalidate_all(); 1150 return __res; 1151 } 1152 1153 typedef basic_string<char> string; 1154 1155 #ifdef _GLIBCXX_USE_WCHAR_T 1156 typedef basic_string<wchar_t> wstring; 1157 #endif 1158 1159 } // namespace __gnu_debug 1160 1161 #endif 1162