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