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