14fee23f9Smrg // Components for manipulating sequences of characters -*- C++ -*- 24fee23f9Smrg 3b1e83836Smrg // Copyright (C) 1997-2022 Free Software Foundation, Inc. 44fee23f9Smrg // 54fee23f9Smrg // This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg // software; you can redistribute it and/or modify it under the 74fee23f9Smrg // terms of the GNU General Public License as published by the 84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg // any later version. 104fee23f9Smrg 114fee23f9Smrg // This library is distributed in the hope that it will be useful, 124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg // GNU General Public License for more details. 154fee23f9Smrg 164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg // 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg // You should have received a copy of the GNU General Public License and 214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg // <http://www.gnu.org/licenses/>. 244fee23f9Smrg 2548fb7bfaSmrg /** @file bits/basic_string.tcc 264fee23f9Smrg * This is an internal header file, included by other library headers. 2748fb7bfaSmrg * Do not attempt to use it directly. @headername{string} 284fee23f9Smrg */ 294fee23f9Smrg 304fee23f9Smrg // 314fee23f9Smrg // ISO C++ 14882: 21 Strings library 324fee23f9Smrg // 334fee23f9Smrg 344fee23f9Smrg // Written by Jason Merrill based upon the specification by Takanori Adachi 354fee23f9Smrg // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 364d5abbe8Smrg // Non-reference-counted implementation written by Paolo Carlini and 374d5abbe8Smrg // updated by Jonathan Wakely for ISO-14882-2011. 384fee23f9Smrg 394fee23f9Smrg #ifndef _BASIC_STRING_TCC 404fee23f9Smrg #define _BASIC_STRING_TCC 1 414fee23f9Smrg 424fee23f9Smrg #pragma GCC system_header 434fee23f9Smrg 4448fb7bfaSmrg #include <bits/cxxabi_forced.h> 454fee23f9Smrg 4648fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default) 4748fb7bfaSmrg { 4848fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 494fee23f9Smrg 504d5abbe8Smrg #if _GLIBCXX_USE_CXX11_ABI 514d5abbe8Smrg 524d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 534d5abbe8Smrg const typename basic_string<_CharT, _Traits, _Alloc>::size_type 544d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>::npos; 554d5abbe8Smrg 564d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 57b1e83836Smrg _GLIBCXX20_CONSTEXPR 584d5abbe8Smrg void 594d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: swap(basic_string & __s)604d5abbe8Smrg swap(basic_string& __s) _GLIBCXX_NOEXCEPT 614d5abbe8Smrg { 62b1e83836Smrg if (this == std::__addressof(__s)) 634d5abbe8Smrg return; 644d5abbe8Smrg 653f4ceed9Smrg _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); 664d5abbe8Smrg 674d5abbe8Smrg if (_M_is_local()) 684d5abbe8Smrg if (__s._M_is_local()) 694d5abbe8Smrg { 704d5abbe8Smrg if (length() && __s.length()) 714d5abbe8Smrg { 724d5abbe8Smrg _CharT __tmp_data[_S_local_capacity + 1]; 734d5abbe8Smrg traits_type::copy(__tmp_data, __s._M_local_buf, 74b1e83836Smrg __s.length() + 1); 754d5abbe8Smrg traits_type::copy(__s._M_local_buf, _M_local_buf, 76b1e83836Smrg length() + 1); 774d5abbe8Smrg traits_type::copy(_M_local_buf, __tmp_data, 78b1e83836Smrg __s.length() + 1); 794d5abbe8Smrg } 804d5abbe8Smrg else if (__s.length()) 814d5abbe8Smrg { 82*0a307195Smrg (void)_M_use_local_data(); 834d5abbe8Smrg traits_type::copy(_M_local_buf, __s._M_local_buf, 84b1e83836Smrg __s.length() + 1); 854d5abbe8Smrg _M_length(__s.length()); 864d5abbe8Smrg __s._M_set_length(0); 874d5abbe8Smrg return; 884d5abbe8Smrg } 894d5abbe8Smrg else if (length()) 904d5abbe8Smrg { 91*0a307195Smrg (void)__s._M_use_local_data(); 924d5abbe8Smrg traits_type::copy(__s._M_local_buf, _M_local_buf, 93b1e83836Smrg length() + 1); 944d5abbe8Smrg __s._M_length(length()); 954d5abbe8Smrg _M_set_length(0); 964d5abbe8Smrg return; 974d5abbe8Smrg } 984d5abbe8Smrg } 994d5abbe8Smrg else 1004d5abbe8Smrg { 1014d5abbe8Smrg const size_type __tmp_capacity = __s._M_allocated_capacity; 102*0a307195Smrg (void)__s._M_use_local_data(); 1034d5abbe8Smrg traits_type::copy(__s._M_local_buf, _M_local_buf, 104b1e83836Smrg length() + 1); 1054d5abbe8Smrg _M_data(__s._M_data()); 1064d5abbe8Smrg __s._M_data(__s._M_local_buf); 1074d5abbe8Smrg _M_capacity(__tmp_capacity); 1084d5abbe8Smrg } 1094d5abbe8Smrg else 1104d5abbe8Smrg { 1114d5abbe8Smrg const size_type __tmp_capacity = _M_allocated_capacity; 1124d5abbe8Smrg if (__s._M_is_local()) 1134d5abbe8Smrg { 114*0a307195Smrg (void)_M_use_local_data(); 1154d5abbe8Smrg traits_type::copy(_M_local_buf, __s._M_local_buf, 116b1e83836Smrg __s.length() + 1); 1174d5abbe8Smrg __s._M_data(_M_data()); 1184d5abbe8Smrg _M_data(_M_local_buf); 1194d5abbe8Smrg } 1204d5abbe8Smrg else 1214d5abbe8Smrg { 1224d5abbe8Smrg pointer __tmp_ptr = _M_data(); 1234d5abbe8Smrg _M_data(__s._M_data()); 1244d5abbe8Smrg __s._M_data(__tmp_ptr); 1254d5abbe8Smrg _M_capacity(__s._M_allocated_capacity); 1264d5abbe8Smrg } 1274d5abbe8Smrg __s._M_capacity(__tmp_capacity); 1284d5abbe8Smrg } 1294d5abbe8Smrg 1304d5abbe8Smrg const size_type __tmp_length = length(); 1314d5abbe8Smrg _M_length(__s.length()); 1324d5abbe8Smrg __s._M_length(__tmp_length); 1334d5abbe8Smrg } 1344d5abbe8Smrg 1354d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 136b1e83836Smrg _GLIBCXX20_CONSTEXPR 1374d5abbe8Smrg typename basic_string<_CharT, _Traits, _Alloc>::pointer 1384d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_create(size_type & __capacity,size_type __old_capacity)1394d5abbe8Smrg _M_create(size_type& __capacity, size_type __old_capacity) 1404d5abbe8Smrg { 1414d5abbe8Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1424d5abbe8Smrg // 83. String::npos vs. string::max_size() 1434d5abbe8Smrg if (__capacity > max_size()) 1444d5abbe8Smrg std::__throw_length_error(__N("basic_string::_M_create")); 1454d5abbe8Smrg 1464d5abbe8Smrg // The below implements an exponential growth policy, necessary to 1474d5abbe8Smrg // meet amortized linear time requirements of the library: see 1484d5abbe8Smrg // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 1494d5abbe8Smrg if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 1504d5abbe8Smrg { 1514d5abbe8Smrg __capacity = 2 * __old_capacity; 1524d5abbe8Smrg // Never allocate a string bigger than max_size. 1534d5abbe8Smrg if (__capacity > max_size()) 1544d5abbe8Smrg __capacity = max_size(); 1554d5abbe8Smrg } 1564d5abbe8Smrg 1574d5abbe8Smrg // NB: Need an array of char_type[__capacity], plus a terminating 1584d5abbe8Smrg // null char_type() element. 1594d5abbe8Smrg return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); 1604d5abbe8Smrg } 1614d5abbe8Smrg 1624d5abbe8Smrg // NB: This is the special case for Input Iterators, used in 1634d5abbe8Smrg // istreambuf_iterators, etc. 1644d5abbe8Smrg // Input Iterators have a cost structure very different from 1654d5abbe8Smrg // pointers, calling for a different coding style. 1664d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 1674d5abbe8Smrg template<typename _InIterator> 168b1e83836Smrg _GLIBCXX20_CONSTEXPR 1694d5abbe8Smrg void 1704d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)1714d5abbe8Smrg _M_construct(_InIterator __beg, _InIterator __end, 1724d5abbe8Smrg std::input_iterator_tag) 1734d5abbe8Smrg { 1744d5abbe8Smrg size_type __len = 0; 1754d5abbe8Smrg size_type __capacity = size_type(_S_local_capacity); 1764d5abbe8Smrg 177b1e83836Smrg pointer __p = _M_use_local_data(); 178b1e83836Smrg 1794d5abbe8Smrg while (__beg != __end && __len < __capacity) 1804d5abbe8Smrg { 181b1e83836Smrg __p[__len++] = *__beg; 1824d5abbe8Smrg ++__beg; 1834d5abbe8Smrg } 1844d5abbe8Smrg 185b1e83836Smrg struct _Guard 1864d5abbe8Smrg { 187b1e83836Smrg _GLIBCXX20_CONSTEXPR 188b1e83836Smrg explicit _Guard(basic_string* __s) : _M_guarded(__s) { } 189b1e83836Smrg 190b1e83836Smrg _GLIBCXX20_CONSTEXPR 191b1e83836Smrg ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); } 192b1e83836Smrg 193b1e83836Smrg basic_string* _M_guarded; 194b1e83836Smrg } __guard(this); 195b1e83836Smrg 1964d5abbe8Smrg while (__beg != __end) 1974d5abbe8Smrg { 1984d5abbe8Smrg if (__len == __capacity) 1994d5abbe8Smrg { 2004d5abbe8Smrg // Allocate more space. 2014d5abbe8Smrg __capacity = __len + 1; 2024d5abbe8Smrg pointer __another = _M_create(__capacity, __len); 2034d5abbe8Smrg this->_S_copy(__another, _M_data(), __len); 2044d5abbe8Smrg _M_dispose(); 2054d5abbe8Smrg _M_data(__another); 2064d5abbe8Smrg _M_capacity(__capacity); 2074d5abbe8Smrg } 208b1e83836Smrg traits_type::assign(_M_data()[__len++], *__beg); 2094d5abbe8Smrg ++__beg; 2104d5abbe8Smrg } 211b1e83836Smrg 212b1e83836Smrg __guard._M_guarded = 0; 2134d5abbe8Smrg 2144d5abbe8Smrg _M_set_length(__len); 2154d5abbe8Smrg } 2164d5abbe8Smrg 2174d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 2184d5abbe8Smrg template<typename _InIterator> 219b1e83836Smrg _GLIBCXX20_CONSTEXPR 2204d5abbe8Smrg void 2214d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)2224d5abbe8Smrg _M_construct(_InIterator __beg, _InIterator __end, 2234d5abbe8Smrg std::forward_iterator_tag) 2244d5abbe8Smrg { 2254d5abbe8Smrg size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); 2264d5abbe8Smrg 2274d5abbe8Smrg if (__dnew > size_type(_S_local_capacity)) 2284d5abbe8Smrg { 2294d5abbe8Smrg _M_data(_M_create(__dnew, size_type(0))); 2304d5abbe8Smrg _M_capacity(__dnew); 2314d5abbe8Smrg } 232b1e83836Smrg else 233b1e83836Smrg _M_use_local_data(); 2344d5abbe8Smrg 2354d5abbe8Smrg // Check for out_of_range and length_error exceptions. 236b1e83836Smrg struct _Guard 2374d5abbe8Smrg { 238b1e83836Smrg _GLIBCXX20_CONSTEXPR 239b1e83836Smrg explicit _Guard(basic_string* __s) : _M_guarded(__s) { } 240b1e83836Smrg 241b1e83836Smrg _GLIBCXX20_CONSTEXPR 242b1e83836Smrg ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); } 243b1e83836Smrg 244b1e83836Smrg basic_string* _M_guarded; 245b1e83836Smrg } __guard(this); 246b1e83836Smrg 247b1e83836Smrg this->_S_copy_chars(_M_data(), __beg, __end); 248b1e83836Smrg 249b1e83836Smrg __guard._M_guarded = 0; 2504d5abbe8Smrg 2514d5abbe8Smrg _M_set_length(__dnew); 2524d5abbe8Smrg } 2534d5abbe8Smrg 2544d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 255b1e83836Smrg _GLIBCXX20_CONSTEXPR 2564d5abbe8Smrg void 2574d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(size_type __n,_CharT __c)2584d5abbe8Smrg _M_construct(size_type __n, _CharT __c) 2594d5abbe8Smrg { 2604d5abbe8Smrg if (__n > size_type(_S_local_capacity)) 2614d5abbe8Smrg { 2624d5abbe8Smrg _M_data(_M_create(__n, size_type(0))); 2634d5abbe8Smrg _M_capacity(__n); 2644d5abbe8Smrg } 265b1e83836Smrg else 266b1e83836Smrg _M_use_local_data(); 2674d5abbe8Smrg 2684d5abbe8Smrg if (__n) 2694d5abbe8Smrg this->_S_assign(_M_data(), __n, __c); 2704d5abbe8Smrg 2714d5abbe8Smrg _M_set_length(__n); 2724d5abbe8Smrg } 2734d5abbe8Smrg 2744d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 275b1e83836Smrg _GLIBCXX20_CONSTEXPR 2764d5abbe8Smrg void 2774d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_assign(const basic_string & __str)2784d5abbe8Smrg _M_assign(const basic_string& __str) 2794d5abbe8Smrg { 280b1e83836Smrg if (this != std::__addressof(__str)) 2814d5abbe8Smrg { 2824d5abbe8Smrg const size_type __rsize = __str.length(); 2834d5abbe8Smrg const size_type __capacity = capacity(); 2844d5abbe8Smrg 2854d5abbe8Smrg if (__rsize > __capacity) 2864d5abbe8Smrg { 2874d5abbe8Smrg size_type __new_capacity = __rsize; 2884d5abbe8Smrg pointer __tmp = _M_create(__new_capacity, __capacity); 2894d5abbe8Smrg _M_dispose(); 2904d5abbe8Smrg _M_data(__tmp); 2914d5abbe8Smrg _M_capacity(__new_capacity); 2924d5abbe8Smrg } 2934d5abbe8Smrg 2944d5abbe8Smrg if (__rsize) 2954d5abbe8Smrg this->_S_copy(_M_data(), __str._M_data(), __rsize); 2964d5abbe8Smrg 2974d5abbe8Smrg _M_set_length(__rsize); 2984d5abbe8Smrg } 2994d5abbe8Smrg } 3004d5abbe8Smrg 3014d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 302b1e83836Smrg _GLIBCXX20_CONSTEXPR 3034d5abbe8Smrg void 3044d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res)3054d5abbe8Smrg reserve(size_type __res) 3064d5abbe8Smrg { 3074d5abbe8Smrg const size_type __capacity = capacity(); 308b1e83836Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 309b1e83836Smrg // 2968. Inconsistencies between basic_string reserve and 310b1e83836Smrg // vector/unordered_map/unordered_set reserve functions 311b1e83836Smrg // P0966 reserve should not shrink 312b1e83836Smrg if (__res <= __capacity) 313b1e83836Smrg return; 314b1e83836Smrg 3154d5abbe8Smrg pointer __tmp = _M_create(__res, __capacity); 3164d5abbe8Smrg this->_S_copy(__tmp, _M_data(), length() + 1); 3174d5abbe8Smrg _M_dispose(); 3184d5abbe8Smrg _M_data(__tmp); 3194d5abbe8Smrg _M_capacity(__res); 3204d5abbe8Smrg } 3214d5abbe8Smrg 3224d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 323b1e83836Smrg _GLIBCXX20_CONSTEXPR 3244d5abbe8Smrg void 3254d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos,size_type __len1,const _CharT * __s,size_type __len2)3264d5abbe8Smrg _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 3274d5abbe8Smrg size_type __len2) 3284d5abbe8Smrg { 3294d5abbe8Smrg const size_type __how_much = length() - __pos - __len1; 3304d5abbe8Smrg 3314d5abbe8Smrg size_type __new_capacity = length() + __len2 - __len1; 3324d5abbe8Smrg pointer __r = _M_create(__new_capacity, capacity()); 3334d5abbe8Smrg 3344d5abbe8Smrg if (__pos) 3354d5abbe8Smrg this->_S_copy(__r, _M_data(), __pos); 3364d5abbe8Smrg if (__s && __len2) 3374d5abbe8Smrg this->_S_copy(__r + __pos, __s, __len2); 3384d5abbe8Smrg if (__how_much) 3394d5abbe8Smrg this->_S_copy(__r + __pos + __len2, 3404d5abbe8Smrg _M_data() + __pos + __len1, __how_much); 3414d5abbe8Smrg 3424d5abbe8Smrg _M_dispose(); 3434d5abbe8Smrg _M_data(__r); 3444d5abbe8Smrg _M_capacity(__new_capacity); 3454d5abbe8Smrg } 3464d5abbe8Smrg 3474d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 348b1e83836Smrg _GLIBCXX20_CONSTEXPR 3494d5abbe8Smrg void 3504d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos,size_type __n)3514d5abbe8Smrg _M_erase(size_type __pos, size_type __n) 3524d5abbe8Smrg { 3534d5abbe8Smrg const size_type __how_much = length() - __pos - __n; 3544d5abbe8Smrg 3554d5abbe8Smrg if (__how_much && __n) 3564d5abbe8Smrg this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); 3574d5abbe8Smrg 3584d5abbe8Smrg _M_set_length(length() - __n); 3594d5abbe8Smrg } 3604d5abbe8Smrg 3614d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 362b1e83836Smrg _GLIBCXX20_CONSTEXPR 363b1e83836Smrg void 364b1e83836Smrg basic_string<_CharT, _Traits, _Alloc>:: reserve()365b1e83836Smrg reserve() 366b1e83836Smrg { 367b1e83836Smrg if (_M_is_local()) 368b1e83836Smrg return; 369b1e83836Smrg 370b1e83836Smrg const size_type __length = length(); 371b1e83836Smrg const size_type __capacity = _M_allocated_capacity; 372b1e83836Smrg 373b1e83836Smrg if (__length <= size_type(_S_local_capacity)) 374b1e83836Smrg { 375b1e83836Smrg this->_S_copy(_M_use_local_data(), _M_data(), __length + 1); 376b1e83836Smrg _M_destroy(__capacity); 377b1e83836Smrg _M_data(_M_local_data()); 378b1e83836Smrg } 379b1e83836Smrg #if __cpp_exceptions 380b1e83836Smrg else if (__length < __capacity) 381b1e83836Smrg try 382b1e83836Smrg { 383b1e83836Smrg pointer __tmp 384b1e83836Smrg = _Alloc_traits::allocate(_M_get_allocator(), __length + 1); 385b1e83836Smrg this->_S_copy(__tmp, _M_data(), __length + 1); 386b1e83836Smrg _M_dispose(); 387b1e83836Smrg _M_data(__tmp); 388b1e83836Smrg _M_capacity(__length); 389b1e83836Smrg } 390b1e83836Smrg catch (const __cxxabiv1::__forced_unwind&) 391b1e83836Smrg { throw; } 392b1e83836Smrg catch (...) 393b1e83836Smrg { /* swallow the exception */ } 394b1e83836Smrg #endif 395b1e83836Smrg } 396b1e83836Smrg 397b1e83836Smrg template<typename _CharT, typename _Traits, typename _Alloc> 398b1e83836Smrg _GLIBCXX20_CONSTEXPR 3994d5abbe8Smrg void 4004d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n,_CharT __c)4014d5abbe8Smrg resize(size_type __n, _CharT __c) 4024d5abbe8Smrg { 4034d5abbe8Smrg const size_type __size = this->size(); 4044d5abbe8Smrg if (__size < __n) 4054d5abbe8Smrg this->append(__n - __size, __c); 4064d5abbe8Smrg else if (__n < __size) 407b17d1066Smrg this->_M_set_length(__n); 4084d5abbe8Smrg } 4094d5abbe8Smrg 4104d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 411b1e83836Smrg _GLIBCXX20_CONSTEXPR 4124d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>& 4134d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_append(const _CharT * __s,size_type __n)4144d5abbe8Smrg _M_append(const _CharT* __s, size_type __n) 4154d5abbe8Smrg { 4164d5abbe8Smrg const size_type __len = __n + this->size(); 4174d5abbe8Smrg 4184d5abbe8Smrg if (__len <= this->capacity()) 4194d5abbe8Smrg { 4204d5abbe8Smrg if (__n) 4214d5abbe8Smrg this->_S_copy(this->_M_data() + this->size(), __s, __n); 4224d5abbe8Smrg } 4234d5abbe8Smrg else 4244d5abbe8Smrg this->_M_mutate(this->size(), size_type(0), __s, __n); 4254d5abbe8Smrg 4264d5abbe8Smrg this->_M_set_length(__len); 4274d5abbe8Smrg return *this; 4284d5abbe8Smrg } 4294d5abbe8Smrg 4304d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 4314d5abbe8Smrg template<typename _InputIterator> 432b1e83836Smrg _GLIBCXX20_CONSTEXPR 4334d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>& 4344d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace_dispatch(const_iterator __i1,const_iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)4354d5abbe8Smrg _M_replace_dispatch(const_iterator __i1, const_iterator __i2, 4364d5abbe8Smrg _InputIterator __k1, _InputIterator __k2, 4374d5abbe8Smrg std::__false_type) 4384d5abbe8Smrg { 439fb8a8121Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 440fb8a8121Smrg // 2788. unintentionally require a default constructible allocator 441fb8a8121Smrg const basic_string __s(__k1, __k2, this->get_allocator()); 4424d5abbe8Smrg const size_type __n1 = __i2 - __i1; 4434d5abbe8Smrg return _M_replace(__i1 - begin(), __n1, __s._M_data(), 4444d5abbe8Smrg __s.size()); 4454d5abbe8Smrg } 4464d5abbe8Smrg 4474d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 448b1e83836Smrg _GLIBCXX20_CONSTEXPR 4494d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>& 4504d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)4514d5abbe8Smrg _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 4524d5abbe8Smrg _CharT __c) 4534d5abbe8Smrg { 4544d5abbe8Smrg _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 4554d5abbe8Smrg 4564d5abbe8Smrg const size_type __old_size = this->size(); 4574d5abbe8Smrg const size_type __new_size = __old_size + __n2 - __n1; 4584d5abbe8Smrg 4594d5abbe8Smrg if (__new_size <= this->capacity()) 4604d5abbe8Smrg { 4613f4ceed9Smrg pointer __p = this->_M_data() + __pos1; 4624d5abbe8Smrg 4634d5abbe8Smrg const size_type __how_much = __old_size - __pos1 - __n1; 4644d5abbe8Smrg if (__how_much && __n1 != __n2) 4654d5abbe8Smrg this->_S_move(__p + __n2, __p + __n1, __how_much); 4664d5abbe8Smrg } 4674d5abbe8Smrg else 4684d5abbe8Smrg this->_M_mutate(__pos1, __n1, 0, __n2); 4694d5abbe8Smrg 4704d5abbe8Smrg if (__n2) 4714d5abbe8Smrg this->_S_assign(this->_M_data() + __pos1, __n2, __c); 4724d5abbe8Smrg 4734d5abbe8Smrg this->_M_set_length(__new_size); 4744d5abbe8Smrg return *this; 4754d5abbe8Smrg } 4764d5abbe8Smrg 4774d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 478b1e83836Smrg _GLIBCXX20_CONSTEXPR 4794d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>& 4804d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)4814d5abbe8Smrg _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 4824d5abbe8Smrg const size_type __len2) 4834d5abbe8Smrg { 4844d5abbe8Smrg _M_check_length(__len1, __len2, "basic_string::_M_replace"); 4854d5abbe8Smrg 4864d5abbe8Smrg const size_type __old_size = this->size(); 4874d5abbe8Smrg const size_type __new_size = __old_size + __len2 - __len1; 4884d5abbe8Smrg 4894d5abbe8Smrg if (__new_size <= this->capacity()) 4904d5abbe8Smrg { 4913f4ceed9Smrg pointer __p = this->_M_data() + __pos; 4924d5abbe8Smrg 4934d5abbe8Smrg const size_type __how_much = __old_size - __pos - __len1; 494b1e83836Smrg #if __cpp_lib_is_constant_evaluated 495b1e83836Smrg if (std::is_constant_evaluated()) 496b1e83836Smrg { 497b1e83836Smrg auto __newp = _Alloc_traits::allocate(_M_get_allocator(), 498b1e83836Smrg __new_size); 499b1e83836Smrg _S_copy(__newp, this->_M_data(), __pos); 500b1e83836Smrg _S_copy(__newp + __pos, __s, __len2); 501b1e83836Smrg _S_copy(__newp + __pos + __len2, __p + __len1, __how_much); 502b1e83836Smrg _S_copy(this->_M_data(), __newp, __new_size); 503b1e83836Smrg this->_M_get_allocator().deallocate(__newp, __new_size); 504b1e83836Smrg } 505b1e83836Smrg else 506b1e83836Smrg #endif 5074d5abbe8Smrg if (_M_disjunct(__s)) 5084d5abbe8Smrg { 5094d5abbe8Smrg if (__how_much && __len1 != __len2) 5104d5abbe8Smrg this->_S_move(__p + __len2, __p + __len1, __how_much); 5114d5abbe8Smrg if (__len2) 5124d5abbe8Smrg this->_S_copy(__p, __s, __len2); 5134d5abbe8Smrg } 5144d5abbe8Smrg else 5154d5abbe8Smrg { 5164d5abbe8Smrg // Work in-place. 5174d5abbe8Smrg if (__len2 && __len2 <= __len1) 5184d5abbe8Smrg this->_S_move(__p, __s, __len2); 5194d5abbe8Smrg if (__how_much && __len1 != __len2) 5204d5abbe8Smrg this->_S_move(__p + __len2, __p + __len1, __how_much); 5214d5abbe8Smrg if (__len2 > __len1) 5224d5abbe8Smrg { 5234d5abbe8Smrg if (__s + __len2 <= __p + __len1) 5244d5abbe8Smrg this->_S_move(__p, __s, __len2); 5254d5abbe8Smrg else if (__s >= __p + __len1) 526b1e83836Smrg { 527b1e83836Smrg // Hint to middle end that __p and __s overlap 528b1e83836Smrg // (PR 98465). 529b1e83836Smrg const size_type __poff = (__s - __p) + (__len2 - __len1); 530b1e83836Smrg this->_S_copy(__p, __p + __poff, __len2); 531b1e83836Smrg } 5324d5abbe8Smrg else 5334d5abbe8Smrg { 5344d5abbe8Smrg const size_type __nleft = (__p + __len1) - __s; 5354d5abbe8Smrg this->_S_move(__p, __s, __nleft); 536*0a307195Smrg // Tell the middle-end that the copy can't overlap 537*0a307195Smrg // (PR105651). 538*0a307195Smrg if (__len2 < __nleft) 539*0a307195Smrg __builtin_unreachable(); 5404d5abbe8Smrg this->_S_copy(__p + __nleft, __p + __len2, 5414d5abbe8Smrg __len2 - __nleft); 5424d5abbe8Smrg } 5434d5abbe8Smrg } 5444d5abbe8Smrg } 5454d5abbe8Smrg } 5464d5abbe8Smrg else 5474d5abbe8Smrg this->_M_mutate(__pos, __len1, __s, __len2); 5484d5abbe8Smrg 5494d5abbe8Smrg this->_M_set_length(__new_size); 5504d5abbe8Smrg return *this; 5514d5abbe8Smrg } 5524d5abbe8Smrg 5534d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc> 554b1e83836Smrg _GLIBCXX20_CONSTEXPR 5554d5abbe8Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 5564d5abbe8Smrg basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT * __s,size_type __n,size_type __pos) const5574d5abbe8Smrg copy(_CharT* __s, size_type __n, size_type __pos) const 5584d5abbe8Smrg { 5594d5abbe8Smrg _M_check(__pos, "basic_string::copy"); 5604d5abbe8Smrg __n = _M_limit(__pos, __n); 5614d5abbe8Smrg __glibcxx_requires_string_len(__s, __n); 5624d5abbe8Smrg if (__n) 5634d5abbe8Smrg _S_copy(__s, _M_data() + __pos, __n); 5644d5abbe8Smrg // 21.3.5.7 par 3: do not append null. (good.) 5654d5abbe8Smrg return __n; 5664d5abbe8Smrg } 5674d5abbe8Smrg 568b1e83836Smrg #if __cplusplus > 202002L 5694fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 570b1e83836Smrg template<typename _Operation> 571b1e83836Smrg constexpr void 5724fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: resize_and_overwrite(const size_type __n,_Operation __op)573*0a307195Smrg resize_and_overwrite(const size_type __n, _Operation __op) 5744fee23f9Smrg { 575b1e83836Smrg const size_type __capacity = capacity(); 576b1e83836Smrg _CharT* __p; 577b1e83836Smrg if (__n > __capacity) 578b1e83836Smrg { 579*0a307195Smrg auto __new_capacity = __n; // Must not allow _M_create to modify __n. 580*0a307195Smrg __p = _M_create(__new_capacity, __capacity); 581b1e83836Smrg this->_S_copy(__p, _M_data(), length()); // exclude trailing null 582b1e83836Smrg #if __cpp_lib_is_constant_evaluated 583b1e83836Smrg if (std::is_constant_evaluated()) 584b1e83836Smrg traits_type::assign(__p + length(), __n - length(), _CharT()); 5854fee23f9Smrg #endif 586b1e83836Smrg _M_dispose(); 587b1e83836Smrg _M_data(__p); 588*0a307195Smrg _M_capacity(__new_capacity); 5894fee23f9Smrg } 590b1e83836Smrg else 591b1e83836Smrg __p = _M_data(); 592b1e83836Smrg struct _Terminator { 593b1e83836Smrg constexpr ~_Terminator() { _M_this->_M_set_length(_M_r); } 594b1e83836Smrg basic_string* _M_this; 595b1e83836Smrg size_type _M_r; 596b1e83836Smrg }; 597b1e83836Smrg _Terminator __term{this}; 598*0a307195Smrg auto __r = std::move(__op)(auto(__p), auto(__n)); 599*0a307195Smrg static_assert(ranges::__detail::__is_integer_like<decltype(__r)>); 600*0a307195Smrg _GLIBCXX_DEBUG_ASSERT(__r >= 0 && __r <= __n); 601*0a307195Smrg __term._M_r = size_type(__r); 602*0a307195Smrg if (__term._M_r > __n) 603*0a307195Smrg __builtin_unreachable(); 6044fee23f9Smrg } 605b1e83836Smrg #endif // C++23 6064fee23f9Smrg 607b1e83836Smrg #endif // _GLIBCXX_USE_CXX11_ABI 6084fee23f9Smrg 609b1e83836Smrg #if __cpp_lib_constexpr_string >= 201907L 610b1e83836Smrg # define _GLIBCXX_STRING_CONSTEXPR constexpr 611b1e83836Smrg #else 612b1e83836Smrg # define _GLIBCXX_STRING_CONSTEXPR 6134fee23f9Smrg #endif 6144fee23f9Smrg 6154fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 616b1e83836Smrg _GLIBCXX20_CONSTEXPR 6174fee23f9Smrg basic_string<_CharT, _Traits, _Alloc> operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)6184fee23f9Smrg operator+(const _CharT* __lhs, 6194fee23f9Smrg const basic_string<_CharT, _Traits, _Alloc>& __rhs) 6204fee23f9Smrg { 6214fee23f9Smrg __glibcxx_requires_string(__lhs); 6224fee23f9Smrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 6234fee23f9Smrg typedef typename __string_type::size_type __size_type; 624fb8a8121Smrg typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 625fb8a8121Smrg rebind<_CharT>::other _Char_alloc_type; 626fb8a8121Smrg typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; 6274fee23f9Smrg const __size_type __len = _Traits::length(__lhs); 628fb8a8121Smrg __string_type __str(_Alloc_traits::_S_select_on_copy( 629fb8a8121Smrg __rhs.get_allocator())); 6304fee23f9Smrg __str.reserve(__len + __rhs.size()); 6314fee23f9Smrg __str.append(__lhs, __len); 6324fee23f9Smrg __str.append(__rhs); 6334fee23f9Smrg return __str; 6344fee23f9Smrg } 6354fee23f9Smrg 6364fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 637b1e83836Smrg _GLIBCXX20_CONSTEXPR 6384fee23f9Smrg basic_string<_CharT, _Traits, _Alloc> operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)6394fee23f9Smrg operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) 6404fee23f9Smrg { 6414fee23f9Smrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 6424fee23f9Smrg typedef typename __string_type::size_type __size_type; 643fb8a8121Smrg typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 644fb8a8121Smrg rebind<_CharT>::other _Char_alloc_type; 645fb8a8121Smrg typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; 646fb8a8121Smrg __string_type __str(_Alloc_traits::_S_select_on_copy( 647fb8a8121Smrg __rhs.get_allocator())); 6484fee23f9Smrg const __size_type __len = __rhs.size(); 6494fee23f9Smrg __str.reserve(__len + 1); 6504fee23f9Smrg __str.append(__size_type(1), __lhs); 6514fee23f9Smrg __str.append(__rhs); 6524fee23f9Smrg return __str; 6534fee23f9Smrg } 6544fee23f9Smrg 6554fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 656b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 6574fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 6584fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT * __s,size_type __pos,size_type __n) const6594fee23f9Smrg find(const _CharT* __s, size_type __pos, size_type __n) const 660b17d1066Smrg _GLIBCXX_NOEXCEPT 6614fee23f9Smrg { 6624fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 6634fee23f9Smrg const size_type __size = this->size(); 6644fee23f9Smrg 6654fee23f9Smrg if (__n == 0) 6664fee23f9Smrg return __pos <= __size ? __pos : npos; 667b17d1066Smrg if (__pos >= __size) 668b17d1066Smrg return npos; 6694fee23f9Smrg 670b17d1066Smrg const _CharT __elem0 = __s[0]; 671b17d1066Smrg const _CharT* const __data = data(); 672b17d1066Smrg const _CharT* __first = __data + __pos; 673b17d1066Smrg const _CharT* const __last = __data + __size; 674b17d1066Smrg size_type __len = __size - __pos; 675b17d1066Smrg 676b17d1066Smrg while (__len >= __n) 6774fee23f9Smrg { 678b17d1066Smrg // Find the first occurrence of __elem0: 679b17d1066Smrg __first = traits_type::find(__first, __len - __n + 1, __elem0); 680b17d1066Smrg if (!__first) 681b17d1066Smrg return npos; 682b17d1066Smrg // Compare the full strings from the first occurrence of __elem0. 683b17d1066Smrg // We already know that __first[0] == __s[0] but compare them again 684b17d1066Smrg // anyway because __s is probably aligned, which helps memcmp. 685b17d1066Smrg if (traits_type::compare(__first, __s, __n) == 0) 686b17d1066Smrg return __first - __data; 687b17d1066Smrg __len = __last - ++__first; 6884fee23f9Smrg } 6894fee23f9Smrg return npos; 6904fee23f9Smrg } 6914fee23f9Smrg 6924fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 693b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 6944fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 6954fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find(_CharT __c,size_type __pos) const69648fb7bfaSmrg find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 6974fee23f9Smrg { 6984fee23f9Smrg size_type __ret = npos; 6994fee23f9Smrg const size_type __size = this->size(); 7004fee23f9Smrg if (__pos < __size) 7014fee23f9Smrg { 7024fee23f9Smrg const _CharT* __data = _M_data(); 7034fee23f9Smrg const size_type __n = __size - __pos; 7044fee23f9Smrg const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 7054fee23f9Smrg if (__p) 7064fee23f9Smrg __ret = __p - __data; 7074fee23f9Smrg } 7084fee23f9Smrg return __ret; 7094fee23f9Smrg } 7104fee23f9Smrg 7114fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 712b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 7134fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 7144fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT * __s,size_type __pos,size_type __n) const7154fee23f9Smrg rfind(const _CharT* __s, size_type __pos, size_type __n) const 716b17d1066Smrg _GLIBCXX_NOEXCEPT 7174fee23f9Smrg { 7184fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 7194fee23f9Smrg const size_type __size = this->size(); 7204fee23f9Smrg if (__n <= __size) 7214fee23f9Smrg { 7224fee23f9Smrg __pos = std::min(size_type(__size - __n), __pos); 7234fee23f9Smrg const _CharT* __data = _M_data(); 7244fee23f9Smrg do 7254fee23f9Smrg { 7264fee23f9Smrg if (traits_type::compare(__data + __pos, __s, __n) == 0) 7274fee23f9Smrg return __pos; 7284fee23f9Smrg } 7294fee23f9Smrg while (__pos-- > 0); 7304fee23f9Smrg } 7314fee23f9Smrg return npos; 7324fee23f9Smrg } 7334fee23f9Smrg 7344fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 735b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 7364fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 7374fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: rfind(_CharT __c,size_type __pos) const73848fb7bfaSmrg rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 7394fee23f9Smrg { 7404fee23f9Smrg size_type __size = this->size(); 7414fee23f9Smrg if (__size) 7424fee23f9Smrg { 7434fee23f9Smrg if (--__size > __pos) 7444fee23f9Smrg __size = __pos; 7454fee23f9Smrg for (++__size; __size-- > 0; ) 7464fee23f9Smrg if (traits_type::eq(_M_data()[__size], __c)) 7474fee23f9Smrg return __size; 7484fee23f9Smrg } 7494fee23f9Smrg return npos; 7504fee23f9Smrg } 7514fee23f9Smrg 7524fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 753b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 7544fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 7554fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT * __s,size_type __pos,size_type __n) const7564fee23f9Smrg find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 757b17d1066Smrg _GLIBCXX_NOEXCEPT 7584fee23f9Smrg { 7594fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 7604fee23f9Smrg for (; __n && __pos < this->size(); ++__pos) 7614fee23f9Smrg { 7624fee23f9Smrg const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 7634fee23f9Smrg if (__p) 7644fee23f9Smrg return __pos; 7654fee23f9Smrg } 7664fee23f9Smrg return npos; 7674fee23f9Smrg } 7684fee23f9Smrg 7694fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 770b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 7714fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 7724fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT * __s,size_type __pos,size_type __n) const7734fee23f9Smrg find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 774b17d1066Smrg _GLIBCXX_NOEXCEPT 7754fee23f9Smrg { 7764fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 7774fee23f9Smrg size_type __size = this->size(); 7784fee23f9Smrg if (__size && __n) 7794fee23f9Smrg { 7804fee23f9Smrg if (--__size > __pos) 7814fee23f9Smrg __size = __pos; 7824fee23f9Smrg do 7834fee23f9Smrg { 7844fee23f9Smrg if (traits_type::find(__s, __n, _M_data()[__size])) 7854fee23f9Smrg return __size; 7864fee23f9Smrg } 7874fee23f9Smrg while (__size-- != 0); 7884fee23f9Smrg } 7894fee23f9Smrg return npos; 7904fee23f9Smrg } 7914fee23f9Smrg 7924fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 793b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 7944fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 7954fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const7964fee23f9Smrg find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 797b17d1066Smrg _GLIBCXX_NOEXCEPT 7984fee23f9Smrg { 7994fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 8004fee23f9Smrg for (; __pos < this->size(); ++__pos) 8014fee23f9Smrg if (!traits_type::find(__s, __n, _M_data()[__pos])) 8024fee23f9Smrg return __pos; 8034fee23f9Smrg return npos; 8044fee23f9Smrg } 8054fee23f9Smrg 8064fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 807b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8084fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 8094fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(_CharT __c,size_type __pos) const81048fb7bfaSmrg find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 8114fee23f9Smrg { 8124fee23f9Smrg for (; __pos < this->size(); ++__pos) 8134fee23f9Smrg if (!traits_type::eq(_M_data()[__pos], __c)) 8144fee23f9Smrg return __pos; 8154fee23f9Smrg return npos; 8164fee23f9Smrg } 8174fee23f9Smrg 8184fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 819b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8204fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 8214fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const8224fee23f9Smrg find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 823b17d1066Smrg _GLIBCXX_NOEXCEPT 8244fee23f9Smrg { 8254fee23f9Smrg __glibcxx_requires_string_len(__s, __n); 8264fee23f9Smrg size_type __size = this->size(); 8274fee23f9Smrg if (__size) 8284fee23f9Smrg { 8294fee23f9Smrg if (--__size > __pos) 8304fee23f9Smrg __size = __pos; 8314fee23f9Smrg do 8324fee23f9Smrg { 8334fee23f9Smrg if (!traits_type::find(__s, __n, _M_data()[__size])) 8344fee23f9Smrg return __size; 8354fee23f9Smrg } 8364fee23f9Smrg while (__size--); 8374fee23f9Smrg } 8384fee23f9Smrg return npos; 8394fee23f9Smrg } 8404fee23f9Smrg 8414fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 842b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8434fee23f9Smrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 8444fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(_CharT __c,size_type __pos) const84548fb7bfaSmrg find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 8464fee23f9Smrg { 8474fee23f9Smrg size_type __size = this->size(); 8484fee23f9Smrg if (__size) 8494fee23f9Smrg { 8504fee23f9Smrg if (--__size > __pos) 8514fee23f9Smrg __size = __pos; 8524fee23f9Smrg do 8534fee23f9Smrg { 8544fee23f9Smrg if (!traits_type::eq(_M_data()[__size], __c)) 8554fee23f9Smrg return __size; 8564fee23f9Smrg } 8574fee23f9Smrg while (__size--); 8584fee23f9Smrg } 8594fee23f9Smrg return npos; 8604fee23f9Smrg } 8614fee23f9Smrg 8624fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 863b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8644fee23f9Smrg int 8654fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n,const basic_string & __str) const8664fee23f9Smrg compare(size_type __pos, size_type __n, const basic_string& __str) const 8674fee23f9Smrg { 8684fee23f9Smrg _M_check(__pos, "basic_string::compare"); 8694fee23f9Smrg __n = _M_limit(__pos, __n); 8704fee23f9Smrg const size_type __osize = __str.size(); 8714fee23f9Smrg const size_type __len = std::min(__n, __osize); 8724fee23f9Smrg int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 8734fee23f9Smrg if (!__r) 8744fee23f9Smrg __r = _S_compare(__n, __osize); 8754fee23f9Smrg return __r; 8764fee23f9Smrg } 8774fee23f9Smrg 8784fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 879b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8804fee23f9Smrg int 8814fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const8824fee23f9Smrg compare(size_type __pos1, size_type __n1, const basic_string& __str, 8834fee23f9Smrg size_type __pos2, size_type __n2) const 8844fee23f9Smrg { 8854fee23f9Smrg _M_check(__pos1, "basic_string::compare"); 8864fee23f9Smrg __str._M_check(__pos2, "basic_string::compare"); 8874fee23f9Smrg __n1 = _M_limit(__pos1, __n1); 8884fee23f9Smrg __n2 = __str._M_limit(__pos2, __n2); 8894fee23f9Smrg const size_type __len = std::min(__n1, __n2); 8904fee23f9Smrg int __r = traits_type::compare(_M_data() + __pos1, 8914fee23f9Smrg __str.data() + __pos2, __len); 8924fee23f9Smrg if (!__r) 8934fee23f9Smrg __r = _S_compare(__n1, __n2); 8944fee23f9Smrg return __r; 8954fee23f9Smrg } 8964fee23f9Smrg 8974fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 898b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 8994fee23f9Smrg int 9004fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT * __s) const901b17d1066Smrg compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT 9024fee23f9Smrg { 9034fee23f9Smrg __glibcxx_requires_string(__s); 9044fee23f9Smrg const size_type __size = this->size(); 9054fee23f9Smrg const size_type __osize = traits_type::length(__s); 9064fee23f9Smrg const size_type __len = std::min(__size, __osize); 9074fee23f9Smrg int __r = traits_type::compare(_M_data(), __s, __len); 9084fee23f9Smrg if (!__r) 9094fee23f9Smrg __r = _S_compare(__size, __osize); 9104fee23f9Smrg return __r; 9114fee23f9Smrg } 9124fee23f9Smrg 9134fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 914b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 9154fee23f9Smrg int 9164fee23f9Smrg basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s) const9174fee23f9Smrg compare(size_type __pos, size_type __n1, const _CharT* __s) const 9184fee23f9Smrg { 9194fee23f9Smrg __glibcxx_requires_string(__s); 9204fee23f9Smrg _M_check(__pos, "basic_string::compare"); 9214fee23f9Smrg __n1 = _M_limit(__pos, __n1); 9224fee23f9Smrg const size_type __osize = traits_type::length(__s); 9234fee23f9Smrg const size_type __len = std::min(__n1, __osize); 9244fee23f9Smrg int __r = traits_type::compare(_M_data() + __pos, __s, __len); 9254fee23f9Smrg if (!__r) 9264fee23f9Smrg __r = _S_compare(__n1, __osize); 9274fee23f9Smrg return __r; 9284fee23f9Smrg } 9294fee23f9Smrg 9304fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 931b1e83836Smrg _GLIBCXX_STRING_CONSTEXPR 9324fee23f9Smrg int 9334fee23f9Smrg basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const9344fee23f9Smrg compare(size_type __pos, size_type __n1, const _CharT* __s, 9354fee23f9Smrg size_type __n2) const 9364fee23f9Smrg { 9374fee23f9Smrg __glibcxx_requires_string_len(__s, __n2); 9384fee23f9Smrg _M_check(__pos, "basic_string::compare"); 9394fee23f9Smrg __n1 = _M_limit(__pos, __n1); 9404fee23f9Smrg const size_type __len = std::min(__n1, __n2); 9414fee23f9Smrg int __r = traits_type::compare(_M_data() + __pos, __s, __len); 9424fee23f9Smrg if (!__r) 9434fee23f9Smrg __r = _S_compare(__n1, __n2); 9444fee23f9Smrg return __r; 9454fee23f9Smrg } 9464fee23f9Smrg 947b1e83836Smrg #undef _GLIBCXX_STRING_CONSTEXPR 948b1e83836Smrg 9494fee23f9Smrg // 21.3.7.9 basic_string::getline and operators 9504fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 9514fee23f9Smrg basic_istream<_CharT, _Traits>& operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)9524fee23f9Smrg operator>>(basic_istream<_CharT, _Traits>& __in, 9534fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>& __str) 9544fee23f9Smrg { 9554fee23f9Smrg typedef basic_istream<_CharT, _Traits> __istream_type; 9564fee23f9Smrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 9574fee23f9Smrg typedef typename __istream_type::ios_base __ios_base; 9584fee23f9Smrg typedef typename __istream_type::int_type __int_type; 9594fee23f9Smrg typedef typename __string_type::size_type __size_type; 9604fee23f9Smrg typedef ctype<_CharT> __ctype_type; 9614fee23f9Smrg typedef typename __ctype_type::ctype_base __ctype_base; 9624fee23f9Smrg 9634fee23f9Smrg __size_type __extracted = 0; 9644fee23f9Smrg typename __ios_base::iostate __err = __ios_base::goodbit; 9654fee23f9Smrg typename __istream_type::sentry __cerb(__in, false); 9664fee23f9Smrg if (__cerb) 9674fee23f9Smrg { 9684fee23f9Smrg __try 9694fee23f9Smrg { 9704fee23f9Smrg // Avoid reallocation for common case. 9714fee23f9Smrg __str.erase(); 9724fee23f9Smrg _CharT __buf[128]; 9734fee23f9Smrg __size_type __len = 0; 9744fee23f9Smrg const streamsize __w = __in.width(); 9754fee23f9Smrg const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 9764fee23f9Smrg : __str.max_size(); 9774fee23f9Smrg const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 9784fee23f9Smrg const __int_type __eof = _Traits::eof(); 9794fee23f9Smrg __int_type __c = __in.rdbuf()->sgetc(); 9804fee23f9Smrg 9814fee23f9Smrg while (__extracted < __n 9824fee23f9Smrg && !_Traits::eq_int_type(__c, __eof) 9834fee23f9Smrg && !__ct.is(__ctype_base::space, 9844fee23f9Smrg _Traits::to_char_type(__c))) 9854fee23f9Smrg { 9864fee23f9Smrg if (__len == sizeof(__buf) / sizeof(_CharT)) 9874fee23f9Smrg { 9884fee23f9Smrg __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 9894fee23f9Smrg __len = 0; 9904fee23f9Smrg } 9914fee23f9Smrg __buf[__len++] = _Traits::to_char_type(__c); 9924fee23f9Smrg ++__extracted; 9934fee23f9Smrg __c = __in.rdbuf()->snextc(); 9944fee23f9Smrg } 9954fee23f9Smrg __str.append(__buf, __len); 9964fee23f9Smrg 997b1e83836Smrg if (__extracted < __n && _Traits::eq_int_type(__c, __eof)) 9984fee23f9Smrg __err |= __ios_base::eofbit; 9994fee23f9Smrg __in.width(0); 10004fee23f9Smrg } 10014fee23f9Smrg __catch(__cxxabiv1::__forced_unwind&) 10024fee23f9Smrg { 10034fee23f9Smrg __in._M_setstate(__ios_base::badbit); 10044fee23f9Smrg __throw_exception_again; 10054fee23f9Smrg } 10064fee23f9Smrg __catch(...) 10074fee23f9Smrg { 10084fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 10094fee23f9Smrg // 91. Description of operator>> and getline() for string<> 10104fee23f9Smrg // might cause endless loop 10114fee23f9Smrg __in._M_setstate(__ios_base::badbit); 10124fee23f9Smrg } 10134fee23f9Smrg } 10144fee23f9Smrg // 211. operator>>(istream&, string&) doesn't set failbit 10154fee23f9Smrg if (!__extracted) 10164fee23f9Smrg __err |= __ios_base::failbit; 10174fee23f9Smrg if (__err) 10184fee23f9Smrg __in.setstate(__err); 10194fee23f9Smrg return __in; 10204fee23f9Smrg } 10214fee23f9Smrg 10224fee23f9Smrg template<typename _CharT, typename _Traits, typename _Alloc> 10234fee23f9Smrg basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)10244fee23f9Smrg getline(basic_istream<_CharT, _Traits>& __in, 10254fee23f9Smrg basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 10264fee23f9Smrg { 10274fee23f9Smrg typedef basic_istream<_CharT, _Traits> __istream_type; 10284fee23f9Smrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 10294fee23f9Smrg typedef typename __istream_type::ios_base __ios_base; 10304fee23f9Smrg typedef typename __istream_type::int_type __int_type; 10314fee23f9Smrg typedef typename __string_type::size_type __size_type; 10324fee23f9Smrg 10334fee23f9Smrg __size_type __extracted = 0; 10344fee23f9Smrg const __size_type __n = __str.max_size(); 10354fee23f9Smrg typename __ios_base::iostate __err = __ios_base::goodbit; 10364fee23f9Smrg typename __istream_type::sentry __cerb(__in, true); 10374fee23f9Smrg if (__cerb) 10384fee23f9Smrg { 10394fee23f9Smrg __try 10404fee23f9Smrg { 10414fee23f9Smrg __str.erase(); 10424fee23f9Smrg const __int_type __idelim = _Traits::to_int_type(__delim); 10434fee23f9Smrg const __int_type __eof = _Traits::eof(); 10444fee23f9Smrg __int_type __c = __in.rdbuf()->sgetc(); 10454fee23f9Smrg 10464fee23f9Smrg while (__extracted < __n 10474fee23f9Smrg && !_Traits::eq_int_type(__c, __eof) 10484fee23f9Smrg && !_Traits::eq_int_type(__c, __idelim)) 10494fee23f9Smrg { 10504fee23f9Smrg __str += _Traits::to_char_type(__c); 10514fee23f9Smrg ++__extracted; 10524fee23f9Smrg __c = __in.rdbuf()->snextc(); 10534fee23f9Smrg } 10544fee23f9Smrg 10554fee23f9Smrg if (_Traits::eq_int_type(__c, __eof)) 10564fee23f9Smrg __err |= __ios_base::eofbit; 10574fee23f9Smrg else if (_Traits::eq_int_type(__c, __idelim)) 10584fee23f9Smrg { 10594fee23f9Smrg ++__extracted; 10604fee23f9Smrg __in.rdbuf()->sbumpc(); 10614fee23f9Smrg } 10624fee23f9Smrg else 10634fee23f9Smrg __err |= __ios_base::failbit; 10644fee23f9Smrg } 10654fee23f9Smrg __catch(__cxxabiv1::__forced_unwind&) 10664fee23f9Smrg { 10674fee23f9Smrg __in._M_setstate(__ios_base::badbit); 10684fee23f9Smrg __throw_exception_again; 10694fee23f9Smrg } 10704fee23f9Smrg __catch(...) 10714fee23f9Smrg { 10724fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 10734fee23f9Smrg // 91. Description of operator>> and getline() for string<> 10744fee23f9Smrg // might cause endless loop 10754fee23f9Smrg __in._M_setstate(__ios_base::badbit); 10764fee23f9Smrg } 10774fee23f9Smrg } 10784fee23f9Smrg if (!__extracted) 10794fee23f9Smrg __err |= __ios_base::failbit; 10804fee23f9Smrg if (__err) 10814fee23f9Smrg __in.setstate(__err); 10824fee23f9Smrg return __in; 10834fee23f9Smrg } 10844fee23f9Smrg 10854fee23f9Smrg // Inhibit implicit instantiations for required instantiations, 10864fee23f9Smrg // which are defined via explicit instantiations elsewhere. 1087b17d1066Smrg #if _GLIBCXX_EXTERN_TEMPLATE 1088fb8a8121Smrg // The explicit instantiation definitions in src/c++11/string-inst.cc and 1089fb8a8121Smrg // src/c++17/string-inst.cc only instantiate the members required for C++17 1090fb8a8121Smrg // and earlier standards (so not C++20's starts_with and ends_with). 1091fb8a8121Smrg // Suppress the explicit instantiation declarations for C++20, so C++20 1092fb8a8121Smrg // code will implicitly instantiate std::string and std::wstring as needed. 1093181254a7Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 10944fee23f9Smrg extern template class basic_string<char>; 1095b17d1066Smrg # elif ! _GLIBCXX_USE_CXX11_ABI 1096b17d1066Smrg // Still need to prevent implicit instantiation of the COW empty rep, 1097b17d1066Smrg // to ensure the definition in libstdc++.so is unique (PR 86138). 1098b17d1066Smrg extern template basic_string<char>::size_type 1099b17d1066Smrg basic_string<char>::_Rep::_S_empty_rep_storage[]; 1100b17d1066Smrg # endif 1101b17d1066Smrg 11024fee23f9Smrg extern template 11034fee23f9Smrg basic_istream<char>& 11044fee23f9Smrg operator>>(basic_istream<char>&, string&); 11054fee23f9Smrg extern template 11064fee23f9Smrg basic_ostream<char>& 11074fee23f9Smrg operator<<(basic_ostream<char>&, const string&); 11084fee23f9Smrg extern template 11094fee23f9Smrg basic_istream<char>& 11104fee23f9Smrg getline(basic_istream<char>&, string&, char); 11114fee23f9Smrg extern template 11124fee23f9Smrg basic_istream<char>& 11134fee23f9Smrg getline(basic_istream<char>&, string&); 11144fee23f9Smrg 11154fee23f9Smrg #ifdef _GLIBCXX_USE_WCHAR_T 1116181254a7Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 11174fee23f9Smrg extern template class basic_string<wchar_t>; 1118b17d1066Smrg # elif ! _GLIBCXX_USE_CXX11_ABI 1119b17d1066Smrg extern template basic_string<wchar_t>::size_type 1120b17d1066Smrg basic_string<wchar_t>::_Rep::_S_empty_rep_storage[]; 1121b17d1066Smrg # endif 1122b17d1066Smrg 11234fee23f9Smrg extern template 11244fee23f9Smrg basic_istream<wchar_t>& 11254fee23f9Smrg operator>>(basic_istream<wchar_t>&, wstring&); 11264fee23f9Smrg extern template 11274fee23f9Smrg basic_ostream<wchar_t>& 11284fee23f9Smrg operator<<(basic_ostream<wchar_t>&, const wstring&); 11294fee23f9Smrg extern template 11304fee23f9Smrg basic_istream<wchar_t>& 11314fee23f9Smrg getline(basic_istream<wchar_t>&, wstring&, wchar_t); 11324fee23f9Smrg extern template 11334fee23f9Smrg basic_istream<wchar_t>& 11344fee23f9Smrg getline(basic_istream<wchar_t>&, wstring&); 1135b17d1066Smrg #endif // _GLIBCXX_USE_WCHAR_T 1136b17d1066Smrg #endif // _GLIBCXX_EXTERN_TEMPLATE 11374fee23f9Smrg 113848fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION 113948fb7bfaSmrg } // namespace std 11404fee23f9Smrg 11414fee23f9Smrg #endif 1142