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