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