11debfc3dSmrg // Components for manipulating sequences of characters -*- C++ -*- 21debfc3dSmrg 3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc. 41debfc3dSmrg // 51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free 61debfc3dSmrg // software; you can redistribute it and/or modify it under the 71debfc3dSmrg // terms of the GNU General Public License as published by the 81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option) 91debfc3dSmrg // any later version. 101debfc3dSmrg 111debfc3dSmrg // This library is distributed in the hope that it will be useful, 121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141debfc3dSmrg // GNU General Public License for more details. 151debfc3dSmrg 161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional 171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version 181debfc3dSmrg // 3.1, as published by the Free Software Foundation. 191debfc3dSmrg 201debfc3dSmrg // You should have received a copy of the GNU General Public License and 211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program; 221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 231debfc3dSmrg // <http://www.gnu.org/licenses/>. 241debfc3dSmrg 251debfc3dSmrg /** @file bits/basic_string.tcc 261debfc3dSmrg * This is an internal header file, included by other library headers. 271debfc3dSmrg * Do not attempt to use it directly. @headername{string} 281debfc3dSmrg */ 291debfc3dSmrg 301debfc3dSmrg // 311debfc3dSmrg // ISO C++ 14882: 21 Strings library 321debfc3dSmrg // 331debfc3dSmrg 341debfc3dSmrg // Written by Jason Merrill based upon the specification by Takanori Adachi 351debfc3dSmrg // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 361debfc3dSmrg // Non-reference-counted implementation written by Paolo Carlini and 371debfc3dSmrg // updated by Jonathan Wakely for ISO-14882-2011. 381debfc3dSmrg 391debfc3dSmrg #ifndef _BASIC_STRING_TCC 401debfc3dSmrg #define _BASIC_STRING_TCC 1 411debfc3dSmrg 421debfc3dSmrg #pragma GCC system_header 431debfc3dSmrg 441debfc3dSmrg #include <bits/cxxabi_forced.h> 451debfc3dSmrg 461debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default) 471debfc3dSmrg { 481debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 491debfc3dSmrg 501debfc3dSmrg #if _GLIBCXX_USE_CXX11_ABI 511debfc3dSmrg 521debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 531debfc3dSmrg const typename basic_string<_CharT, _Traits, _Alloc>::size_type 541debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::npos; 551debfc3dSmrg 561debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 571debfc3dSmrg void 581debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: swap(basic_string & __s)591debfc3dSmrg swap(basic_string& __s) _GLIBCXX_NOEXCEPT 601debfc3dSmrg { 611debfc3dSmrg if (this == &__s) 621debfc3dSmrg return; 631debfc3dSmrg 641debfc3dSmrg _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); 651debfc3dSmrg 661debfc3dSmrg if (_M_is_local()) 671debfc3dSmrg if (__s._M_is_local()) 681debfc3dSmrg { 691debfc3dSmrg if (length() && __s.length()) 701debfc3dSmrg { 711debfc3dSmrg _CharT __tmp_data[_S_local_capacity + 1]; 721debfc3dSmrg traits_type::copy(__tmp_data, __s._M_local_buf, 731debfc3dSmrg _S_local_capacity + 1); 741debfc3dSmrg traits_type::copy(__s._M_local_buf, _M_local_buf, 751debfc3dSmrg _S_local_capacity + 1); 761debfc3dSmrg traits_type::copy(_M_local_buf, __tmp_data, 771debfc3dSmrg _S_local_capacity + 1); 781debfc3dSmrg } 791debfc3dSmrg else if (__s.length()) 801debfc3dSmrg { 811debfc3dSmrg traits_type::copy(_M_local_buf, __s._M_local_buf, 821debfc3dSmrg _S_local_capacity + 1); 831debfc3dSmrg _M_length(__s.length()); 841debfc3dSmrg __s._M_set_length(0); 851debfc3dSmrg return; 861debfc3dSmrg } 871debfc3dSmrg else if (length()) 881debfc3dSmrg { 891debfc3dSmrg traits_type::copy(__s._M_local_buf, _M_local_buf, 901debfc3dSmrg _S_local_capacity + 1); 911debfc3dSmrg __s._M_length(length()); 921debfc3dSmrg _M_set_length(0); 931debfc3dSmrg return; 941debfc3dSmrg } 951debfc3dSmrg } 961debfc3dSmrg else 971debfc3dSmrg { 981debfc3dSmrg const size_type __tmp_capacity = __s._M_allocated_capacity; 991debfc3dSmrg traits_type::copy(__s._M_local_buf, _M_local_buf, 1001debfc3dSmrg _S_local_capacity + 1); 1011debfc3dSmrg _M_data(__s._M_data()); 1021debfc3dSmrg __s._M_data(__s._M_local_buf); 1031debfc3dSmrg _M_capacity(__tmp_capacity); 1041debfc3dSmrg } 1051debfc3dSmrg else 1061debfc3dSmrg { 1071debfc3dSmrg const size_type __tmp_capacity = _M_allocated_capacity; 1081debfc3dSmrg if (__s._M_is_local()) 1091debfc3dSmrg { 1101debfc3dSmrg traits_type::copy(_M_local_buf, __s._M_local_buf, 1111debfc3dSmrg _S_local_capacity + 1); 1121debfc3dSmrg __s._M_data(_M_data()); 1131debfc3dSmrg _M_data(_M_local_buf); 1141debfc3dSmrg } 1151debfc3dSmrg else 1161debfc3dSmrg { 1171debfc3dSmrg pointer __tmp_ptr = _M_data(); 1181debfc3dSmrg _M_data(__s._M_data()); 1191debfc3dSmrg __s._M_data(__tmp_ptr); 1201debfc3dSmrg _M_capacity(__s._M_allocated_capacity); 1211debfc3dSmrg } 1221debfc3dSmrg __s._M_capacity(__tmp_capacity); 1231debfc3dSmrg } 1241debfc3dSmrg 1251debfc3dSmrg const size_type __tmp_length = length(); 1261debfc3dSmrg _M_length(__s.length()); 1271debfc3dSmrg __s._M_length(__tmp_length); 1281debfc3dSmrg } 1291debfc3dSmrg 1301debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 1311debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::pointer 1321debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_create(size_type & __capacity,size_type __old_capacity)1331debfc3dSmrg _M_create(size_type& __capacity, size_type __old_capacity) 1341debfc3dSmrg { 1351debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1361debfc3dSmrg // 83. String::npos vs. string::max_size() 1371debfc3dSmrg if (__capacity > max_size()) 1381debfc3dSmrg std::__throw_length_error(__N("basic_string::_M_create")); 1391debfc3dSmrg 1401debfc3dSmrg // The below implements an exponential growth policy, necessary to 1411debfc3dSmrg // meet amortized linear time requirements of the library: see 1421debfc3dSmrg // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 1431debfc3dSmrg if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 1441debfc3dSmrg { 1451debfc3dSmrg __capacity = 2 * __old_capacity; 1461debfc3dSmrg // Never allocate a string bigger than max_size. 1471debfc3dSmrg if (__capacity > max_size()) 1481debfc3dSmrg __capacity = max_size(); 1491debfc3dSmrg } 1501debfc3dSmrg 1511debfc3dSmrg // NB: Need an array of char_type[__capacity], plus a terminating 1521debfc3dSmrg // null char_type() element. 1531debfc3dSmrg return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); 1541debfc3dSmrg } 1551debfc3dSmrg 1561debfc3dSmrg // NB: This is the special case for Input Iterators, used in 1571debfc3dSmrg // istreambuf_iterators, etc. 1581debfc3dSmrg // Input Iterators have a cost structure very different from 1591debfc3dSmrg // pointers, calling for a different coding style. 1601debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 1611debfc3dSmrg template<typename _InIterator> 1621debfc3dSmrg void 1631debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)1641debfc3dSmrg _M_construct(_InIterator __beg, _InIterator __end, 1651debfc3dSmrg std::input_iterator_tag) 1661debfc3dSmrg { 1671debfc3dSmrg size_type __len = 0; 1681debfc3dSmrg size_type __capacity = size_type(_S_local_capacity); 1691debfc3dSmrg 1701debfc3dSmrg while (__beg != __end && __len < __capacity) 1711debfc3dSmrg { 1721debfc3dSmrg _M_data()[__len++] = *__beg; 1731debfc3dSmrg ++__beg; 1741debfc3dSmrg } 1751debfc3dSmrg 1761debfc3dSmrg __try 1771debfc3dSmrg { 1781debfc3dSmrg while (__beg != __end) 1791debfc3dSmrg { 1801debfc3dSmrg if (__len == __capacity) 1811debfc3dSmrg { 1821debfc3dSmrg // Allocate more space. 1831debfc3dSmrg __capacity = __len + 1; 1841debfc3dSmrg pointer __another = _M_create(__capacity, __len); 1851debfc3dSmrg this->_S_copy(__another, _M_data(), __len); 1861debfc3dSmrg _M_dispose(); 1871debfc3dSmrg _M_data(__another); 1881debfc3dSmrg _M_capacity(__capacity); 1891debfc3dSmrg } 1901debfc3dSmrg _M_data()[__len++] = *__beg; 1911debfc3dSmrg ++__beg; 1921debfc3dSmrg } 1931debfc3dSmrg } 1941debfc3dSmrg __catch(...) 1951debfc3dSmrg { 1961debfc3dSmrg _M_dispose(); 1971debfc3dSmrg __throw_exception_again; 1981debfc3dSmrg } 1991debfc3dSmrg 2001debfc3dSmrg _M_set_length(__len); 2011debfc3dSmrg } 2021debfc3dSmrg 2031debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 2041debfc3dSmrg template<typename _InIterator> 2051debfc3dSmrg void 2061debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)2071debfc3dSmrg _M_construct(_InIterator __beg, _InIterator __end, 2081debfc3dSmrg std::forward_iterator_tag) 2091debfc3dSmrg { 2101debfc3dSmrg // NB: Not required, but considered best practice. 2111debfc3dSmrg if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 2121debfc3dSmrg std::__throw_logic_error(__N("basic_string::" 2131debfc3dSmrg "_M_construct null not valid")); 2141debfc3dSmrg 2151debfc3dSmrg size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); 2161debfc3dSmrg 2171debfc3dSmrg if (__dnew > size_type(_S_local_capacity)) 2181debfc3dSmrg { 2191debfc3dSmrg _M_data(_M_create(__dnew, size_type(0))); 2201debfc3dSmrg _M_capacity(__dnew); 2211debfc3dSmrg } 2221debfc3dSmrg 2231debfc3dSmrg // Check for out_of_range and length_error exceptions. 2241debfc3dSmrg __try 2251debfc3dSmrg { this->_S_copy_chars(_M_data(), __beg, __end); } 2261debfc3dSmrg __catch(...) 2271debfc3dSmrg { 2281debfc3dSmrg _M_dispose(); 2291debfc3dSmrg __throw_exception_again; 2301debfc3dSmrg } 2311debfc3dSmrg 2321debfc3dSmrg _M_set_length(__dnew); 2331debfc3dSmrg } 2341debfc3dSmrg 2351debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 2361debfc3dSmrg void 2371debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_construct(size_type __n,_CharT __c)2381debfc3dSmrg _M_construct(size_type __n, _CharT __c) 2391debfc3dSmrg { 2401debfc3dSmrg if (__n > size_type(_S_local_capacity)) 2411debfc3dSmrg { 2421debfc3dSmrg _M_data(_M_create(__n, size_type(0))); 2431debfc3dSmrg _M_capacity(__n); 2441debfc3dSmrg } 2451debfc3dSmrg 2461debfc3dSmrg if (__n) 2471debfc3dSmrg this->_S_assign(_M_data(), __n, __c); 2481debfc3dSmrg 2491debfc3dSmrg _M_set_length(__n); 2501debfc3dSmrg } 2511debfc3dSmrg 2521debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 2531debfc3dSmrg void 2541debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_assign(const basic_string & __str)2551debfc3dSmrg _M_assign(const basic_string& __str) 2561debfc3dSmrg { 2571debfc3dSmrg if (this != &__str) 2581debfc3dSmrg { 2591debfc3dSmrg const size_type __rsize = __str.length(); 2601debfc3dSmrg const size_type __capacity = capacity(); 2611debfc3dSmrg 2621debfc3dSmrg if (__rsize > __capacity) 2631debfc3dSmrg { 2641debfc3dSmrg size_type __new_capacity = __rsize; 2651debfc3dSmrg pointer __tmp = _M_create(__new_capacity, __capacity); 2661debfc3dSmrg _M_dispose(); 2671debfc3dSmrg _M_data(__tmp); 2681debfc3dSmrg _M_capacity(__new_capacity); 2691debfc3dSmrg } 2701debfc3dSmrg 2711debfc3dSmrg if (__rsize) 2721debfc3dSmrg this->_S_copy(_M_data(), __str._M_data(), __rsize); 2731debfc3dSmrg 2741debfc3dSmrg _M_set_length(__rsize); 2751debfc3dSmrg } 2761debfc3dSmrg } 2771debfc3dSmrg 2781debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 2791debfc3dSmrg void 2801debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res)2811debfc3dSmrg reserve(size_type __res) 2821debfc3dSmrg { 2831debfc3dSmrg // Make sure we don't shrink below the current size. 2841debfc3dSmrg if (__res < length()) 2851debfc3dSmrg __res = length(); 2861debfc3dSmrg 2871debfc3dSmrg const size_type __capacity = capacity(); 2881debfc3dSmrg if (__res != __capacity) 2891debfc3dSmrg { 2901debfc3dSmrg if (__res > __capacity 2911debfc3dSmrg || __res > size_type(_S_local_capacity)) 2921debfc3dSmrg { 2931debfc3dSmrg pointer __tmp = _M_create(__res, __capacity); 2941debfc3dSmrg this->_S_copy(__tmp, _M_data(), length() + 1); 2951debfc3dSmrg _M_dispose(); 2961debfc3dSmrg _M_data(__tmp); 2971debfc3dSmrg _M_capacity(__res); 2981debfc3dSmrg } 2991debfc3dSmrg else if (!_M_is_local()) 3001debfc3dSmrg { 3011debfc3dSmrg this->_S_copy(_M_local_data(), _M_data(), length() + 1); 3021debfc3dSmrg _M_destroy(__capacity); 3031debfc3dSmrg _M_data(_M_local_data()); 3041debfc3dSmrg } 3051debfc3dSmrg } 3061debfc3dSmrg } 3071debfc3dSmrg 3081debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3091debfc3dSmrg void 3101debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos,size_type __len1,const _CharT * __s,size_type __len2)3111debfc3dSmrg _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 3121debfc3dSmrg size_type __len2) 3131debfc3dSmrg { 3141debfc3dSmrg const size_type __how_much = length() - __pos - __len1; 3151debfc3dSmrg 3161debfc3dSmrg size_type __new_capacity = length() + __len2 - __len1; 3171debfc3dSmrg pointer __r = _M_create(__new_capacity, capacity()); 3181debfc3dSmrg 3191debfc3dSmrg if (__pos) 3201debfc3dSmrg this->_S_copy(__r, _M_data(), __pos); 3211debfc3dSmrg if (__s && __len2) 3221debfc3dSmrg this->_S_copy(__r + __pos, __s, __len2); 3231debfc3dSmrg if (__how_much) 3241debfc3dSmrg this->_S_copy(__r + __pos + __len2, 3251debfc3dSmrg _M_data() + __pos + __len1, __how_much); 3261debfc3dSmrg 3271debfc3dSmrg _M_dispose(); 3281debfc3dSmrg _M_data(__r); 3291debfc3dSmrg _M_capacity(__new_capacity); 3301debfc3dSmrg } 3311debfc3dSmrg 3321debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3331debfc3dSmrg void 3341debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos,size_type __n)3351debfc3dSmrg _M_erase(size_type __pos, size_type __n) 3361debfc3dSmrg { 3371debfc3dSmrg const size_type __how_much = length() - __pos - __n; 3381debfc3dSmrg 3391debfc3dSmrg if (__how_much && __n) 3401debfc3dSmrg this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); 3411debfc3dSmrg 3421debfc3dSmrg _M_set_length(length() - __n); 3431debfc3dSmrg } 3441debfc3dSmrg 3451debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3461debfc3dSmrg void 3471debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n,_CharT __c)3481debfc3dSmrg resize(size_type __n, _CharT __c) 3491debfc3dSmrg { 3501debfc3dSmrg const size_type __size = this->size(); 3511debfc3dSmrg if (__size < __n) 3521debfc3dSmrg this->append(__n - __size, __c); 3531debfc3dSmrg else if (__n < __size) 3541debfc3dSmrg this->_M_set_length(__n); 3551debfc3dSmrg } 3561debfc3dSmrg 3571debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3581debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 3591debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_append(const _CharT * __s,size_type __n)3601debfc3dSmrg _M_append(const _CharT* __s, size_type __n) 3611debfc3dSmrg { 3621debfc3dSmrg const size_type __len = __n + this->size(); 3631debfc3dSmrg 3641debfc3dSmrg if (__len <= this->capacity()) 3651debfc3dSmrg { 3661debfc3dSmrg if (__n) 3671debfc3dSmrg this->_S_copy(this->_M_data() + this->size(), __s, __n); 3681debfc3dSmrg } 3691debfc3dSmrg else 3701debfc3dSmrg this->_M_mutate(this->size(), size_type(0), __s, __n); 3711debfc3dSmrg 3721debfc3dSmrg this->_M_set_length(__len); 3731debfc3dSmrg return *this; 3741debfc3dSmrg } 3751debfc3dSmrg 3761debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3771debfc3dSmrg template<typename _InputIterator> 3781debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 3791debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace_dispatch(const_iterator __i1,const_iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)3801debfc3dSmrg _M_replace_dispatch(const_iterator __i1, const_iterator __i2, 3811debfc3dSmrg _InputIterator __k1, _InputIterator __k2, 3821debfc3dSmrg std::__false_type) 3831debfc3dSmrg { 384*8feb0f0bSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 385*8feb0f0bSmrg // 2788. unintentionally require a default constructible allocator 386*8feb0f0bSmrg const basic_string __s(__k1, __k2, this->get_allocator()); 3871debfc3dSmrg const size_type __n1 = __i2 - __i1; 3881debfc3dSmrg return _M_replace(__i1 - begin(), __n1, __s._M_data(), 3891debfc3dSmrg __s.size()); 3901debfc3dSmrg } 3911debfc3dSmrg 3921debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 3931debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 3941debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)3951debfc3dSmrg _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 3961debfc3dSmrg _CharT __c) 3971debfc3dSmrg { 3981debfc3dSmrg _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 3991debfc3dSmrg 4001debfc3dSmrg const size_type __old_size = this->size(); 4011debfc3dSmrg const size_type __new_size = __old_size + __n2 - __n1; 4021debfc3dSmrg 4031debfc3dSmrg if (__new_size <= this->capacity()) 4041debfc3dSmrg { 4051debfc3dSmrg pointer __p = this->_M_data() + __pos1; 4061debfc3dSmrg 4071debfc3dSmrg const size_type __how_much = __old_size - __pos1 - __n1; 4081debfc3dSmrg if (__how_much && __n1 != __n2) 4091debfc3dSmrg this->_S_move(__p + __n2, __p + __n1, __how_much); 4101debfc3dSmrg } 4111debfc3dSmrg else 4121debfc3dSmrg this->_M_mutate(__pos1, __n1, 0, __n2); 4131debfc3dSmrg 4141debfc3dSmrg if (__n2) 4151debfc3dSmrg this->_S_assign(this->_M_data() + __pos1, __n2, __c); 4161debfc3dSmrg 4171debfc3dSmrg this->_M_set_length(__new_size); 4181debfc3dSmrg return *this; 4191debfc3dSmrg } 4201debfc3dSmrg 4211debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 4221debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 4231debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: _M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)4241debfc3dSmrg _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 4251debfc3dSmrg const size_type __len2) 4261debfc3dSmrg { 4271debfc3dSmrg _M_check_length(__len1, __len2, "basic_string::_M_replace"); 4281debfc3dSmrg 4291debfc3dSmrg const size_type __old_size = this->size(); 4301debfc3dSmrg const size_type __new_size = __old_size + __len2 - __len1; 4311debfc3dSmrg 4321debfc3dSmrg if (__new_size <= this->capacity()) 4331debfc3dSmrg { 4341debfc3dSmrg pointer __p = this->_M_data() + __pos; 4351debfc3dSmrg 4361debfc3dSmrg const size_type __how_much = __old_size - __pos - __len1; 4371debfc3dSmrg if (_M_disjunct(__s)) 4381debfc3dSmrg { 4391debfc3dSmrg if (__how_much && __len1 != __len2) 4401debfc3dSmrg this->_S_move(__p + __len2, __p + __len1, __how_much); 4411debfc3dSmrg if (__len2) 4421debfc3dSmrg this->_S_copy(__p, __s, __len2); 4431debfc3dSmrg } 4441debfc3dSmrg else 4451debfc3dSmrg { 4461debfc3dSmrg // Work in-place. 4471debfc3dSmrg if (__len2 && __len2 <= __len1) 4481debfc3dSmrg this->_S_move(__p, __s, __len2); 4491debfc3dSmrg if (__how_much && __len1 != __len2) 4501debfc3dSmrg this->_S_move(__p + __len2, __p + __len1, __how_much); 4511debfc3dSmrg if (__len2 > __len1) 4521debfc3dSmrg { 4531debfc3dSmrg if (__s + __len2 <= __p + __len1) 4541debfc3dSmrg this->_S_move(__p, __s, __len2); 4551debfc3dSmrg else if (__s >= __p + __len1) 4561debfc3dSmrg this->_S_copy(__p, __s + __len2 - __len1, __len2); 4571debfc3dSmrg else 4581debfc3dSmrg { 4591debfc3dSmrg const size_type __nleft = (__p + __len1) - __s; 4601debfc3dSmrg this->_S_move(__p, __s, __nleft); 4611debfc3dSmrg this->_S_copy(__p + __nleft, __p + __len2, 4621debfc3dSmrg __len2 - __nleft); 4631debfc3dSmrg } 4641debfc3dSmrg } 4651debfc3dSmrg } 4661debfc3dSmrg } 4671debfc3dSmrg else 4681debfc3dSmrg this->_M_mutate(__pos, __len1, __s, __len2); 4691debfc3dSmrg 4701debfc3dSmrg this->_M_set_length(__new_size); 4711debfc3dSmrg return *this; 4721debfc3dSmrg } 4731debfc3dSmrg 4741debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 4751debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 4761debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT * __s,size_type __n,size_type __pos) const4771debfc3dSmrg copy(_CharT* __s, size_type __n, size_type __pos) const 4781debfc3dSmrg { 4791debfc3dSmrg _M_check(__pos, "basic_string::copy"); 4801debfc3dSmrg __n = _M_limit(__pos, __n); 4811debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 4821debfc3dSmrg if (__n) 4831debfc3dSmrg _S_copy(__s, _M_data() + __pos, __n); 4841debfc3dSmrg // 21.3.5.7 par 3: do not append null. (good.) 4851debfc3dSmrg return __n; 4861debfc3dSmrg } 4871debfc3dSmrg 4881debfc3dSmrg #else // !_GLIBCXX_USE_CXX11_ABI 4891debfc3dSmrg 4901debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 4911debfc3dSmrg const typename basic_string<_CharT, _Traits, _Alloc>::size_type 4921debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 4931debfc3dSmrg _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; 4941debfc3dSmrg 4951debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 4961debfc3dSmrg const _CharT 4971debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 4981debfc3dSmrg _Rep::_S_terminal = _CharT(); 4991debfc3dSmrg 5001debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 5011debfc3dSmrg const typename basic_string<_CharT, _Traits, _Alloc>::size_type 5021debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::npos; 5031debfc3dSmrg 5041debfc3dSmrg // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) 5051debfc3dSmrg // at static init time (before static ctors are run). 5061debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 5071debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 5081debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ 5091debfc3dSmrg (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / 5101debfc3dSmrg sizeof(size_type)]; 5111debfc3dSmrg 5121debfc3dSmrg // NB: This is the special case for Input Iterators, used in 5131debfc3dSmrg // istreambuf_iterators, etc. 5141debfc3dSmrg // Input Iterators have a cost structure very different from 5151debfc3dSmrg // pointers, calling for a different coding style. 5161debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 5171debfc3dSmrg template<typename _InIterator> 5181debfc3dSmrg _CharT* 5191debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 5201debfc3dSmrg _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 5211debfc3dSmrg input_iterator_tag) 5221debfc3dSmrg { 5231debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 5241debfc3dSmrg if (__beg == __end && __a == _Alloc()) 5251debfc3dSmrg return _S_empty_rep()._M_refdata(); 5261debfc3dSmrg #endif 5271debfc3dSmrg // Avoid reallocation for common case. 5281debfc3dSmrg _CharT __buf[128]; 5291debfc3dSmrg size_type __len = 0; 5301debfc3dSmrg while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) 5311debfc3dSmrg { 5321debfc3dSmrg __buf[__len++] = *__beg; 5331debfc3dSmrg ++__beg; 5341debfc3dSmrg } 5351debfc3dSmrg _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); 5361debfc3dSmrg _M_copy(__r->_M_refdata(), __buf, __len); 5371debfc3dSmrg __try 5381debfc3dSmrg { 5391debfc3dSmrg while (__beg != __end) 5401debfc3dSmrg { 5411debfc3dSmrg if (__len == __r->_M_capacity) 5421debfc3dSmrg { 5431debfc3dSmrg // Allocate more space. 5441debfc3dSmrg _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); 5451debfc3dSmrg _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); 5461debfc3dSmrg __r->_M_destroy(__a); 5471debfc3dSmrg __r = __another; 5481debfc3dSmrg } 5491debfc3dSmrg __r->_M_refdata()[__len++] = *__beg; 5501debfc3dSmrg ++__beg; 5511debfc3dSmrg } 5521debfc3dSmrg } 5531debfc3dSmrg __catch(...) 5541debfc3dSmrg { 5551debfc3dSmrg __r->_M_destroy(__a); 5561debfc3dSmrg __throw_exception_again; 5571debfc3dSmrg } 5581debfc3dSmrg __r->_M_set_length_and_sharable(__len); 5591debfc3dSmrg return __r->_M_refdata(); 5601debfc3dSmrg } 5611debfc3dSmrg 5621debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 5631debfc3dSmrg template <typename _InIterator> 5641debfc3dSmrg _CharT* 5651debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 5661debfc3dSmrg _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 5671debfc3dSmrg forward_iterator_tag) 5681debfc3dSmrg { 5691debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 5701debfc3dSmrg if (__beg == __end && __a == _Alloc()) 5711debfc3dSmrg return _S_empty_rep()._M_refdata(); 5721debfc3dSmrg #endif 5731debfc3dSmrg // NB: Not required, but considered best practice. 5741debfc3dSmrg if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 5751debfc3dSmrg __throw_logic_error(__N("basic_string::_S_construct null not valid")); 5761debfc3dSmrg 5771debfc3dSmrg const size_type __dnew = static_cast<size_type>(std::distance(__beg, 5781debfc3dSmrg __end)); 5791debfc3dSmrg // Check for out_of_range and length_error exceptions. 5801debfc3dSmrg _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); 5811debfc3dSmrg __try 5821debfc3dSmrg { _S_copy_chars(__r->_M_refdata(), __beg, __end); } 5831debfc3dSmrg __catch(...) 5841debfc3dSmrg { 5851debfc3dSmrg __r->_M_destroy(__a); 5861debfc3dSmrg __throw_exception_again; 5871debfc3dSmrg } 5881debfc3dSmrg __r->_M_set_length_and_sharable(__dnew); 5891debfc3dSmrg return __r->_M_refdata(); 5901debfc3dSmrg } 5911debfc3dSmrg 5921debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 5931debfc3dSmrg _CharT* 5941debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 5951debfc3dSmrg _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 5961debfc3dSmrg { 5971debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 5981debfc3dSmrg if (__n == 0 && __a == _Alloc()) 5991debfc3dSmrg return _S_empty_rep()._M_refdata(); 6001debfc3dSmrg #endif 6011debfc3dSmrg // Check for out_of_range and length_error exceptions. 6021debfc3dSmrg _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); 6031debfc3dSmrg if (__n) 6041debfc3dSmrg _M_assign(__r->_M_refdata(), __n, __c); 6051debfc3dSmrg 6061debfc3dSmrg __r->_M_set_length_and_sharable(__n); 6071debfc3dSmrg return __r->_M_refdata(); 6081debfc3dSmrg } 6091debfc3dSmrg 6101debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6111debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6121debfc3dSmrg basic_string(const basic_string& __str) 6131debfc3dSmrg : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), 6141debfc3dSmrg __str.get_allocator()), 6151debfc3dSmrg __str.get_allocator()) 6161debfc3dSmrg { } 6171debfc3dSmrg 6181debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6191debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6201debfc3dSmrg basic_string(const _Alloc& __a) 6211debfc3dSmrg : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) 6221debfc3dSmrg { } 6231debfc3dSmrg 6241debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6251debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6261debfc3dSmrg basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a) 6271debfc3dSmrg : _M_dataplus(_S_construct(__str._M_data() 6281debfc3dSmrg + __str._M_check(__pos, 6291debfc3dSmrg "basic_string::basic_string"), 6301debfc3dSmrg __str._M_data() + __str._M_limit(__pos, npos) 6311debfc3dSmrg + __pos, __a), __a) 6321debfc3dSmrg { } 6331debfc3dSmrg 6341debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6351debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6361debfc3dSmrg basic_string(const basic_string& __str, size_type __pos, size_type __n) 6371debfc3dSmrg : _M_dataplus(_S_construct(__str._M_data() 6381debfc3dSmrg + __str._M_check(__pos, 6391debfc3dSmrg "basic_string::basic_string"), 6401debfc3dSmrg __str._M_data() + __str._M_limit(__pos, __n) 6411debfc3dSmrg + __pos, _Alloc()), _Alloc()) 6421debfc3dSmrg { } 6431debfc3dSmrg 6441debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6451debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6461debfc3dSmrg basic_string(const basic_string& __str, size_type __pos, 6471debfc3dSmrg size_type __n, const _Alloc& __a) 6481debfc3dSmrg : _M_dataplus(_S_construct(__str._M_data() 6491debfc3dSmrg + __str._M_check(__pos, 6501debfc3dSmrg "basic_string::basic_string"), 6511debfc3dSmrg __str._M_data() + __str._M_limit(__pos, __n) 6521debfc3dSmrg + __pos, __a), __a) 6531debfc3dSmrg { } 6541debfc3dSmrg 6551debfc3dSmrg // TBD: DPG annotate 6561debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6571debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6581debfc3dSmrg basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) 6591debfc3dSmrg : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) 6601debfc3dSmrg { } 6611debfc3dSmrg 6621debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6631debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6641debfc3dSmrg basic_string(size_type __n, _CharT __c, const _Alloc& __a) 6651debfc3dSmrg : _M_dataplus(_S_construct(__n, __c, __a), __a) 6661debfc3dSmrg { } 6671debfc3dSmrg 6681debfc3dSmrg // TBD: DPG annotate 6691debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6701debfc3dSmrg template<typename _InputIterator> 6711debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6721debfc3dSmrg basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) 6731debfc3dSmrg : _M_dataplus(_S_construct(__beg, __end, __a), __a) 6741debfc3dSmrg { } 6751debfc3dSmrg 6761debfc3dSmrg #if __cplusplus >= 201103L 6771debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6781debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6791debfc3dSmrg basic_string(initializer_list<_CharT> __l, const _Alloc& __a) 6801debfc3dSmrg : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a) 6811debfc3dSmrg { } 6821debfc3dSmrg #endif 6831debfc3dSmrg 6841debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 6851debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 6861debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 6871debfc3dSmrg assign(const basic_string& __str) 6881debfc3dSmrg { 6891debfc3dSmrg if (_M_rep() != __str._M_rep()) 6901debfc3dSmrg { 6911debfc3dSmrg // XXX MT 6921debfc3dSmrg const allocator_type __a = this->get_allocator(); 6931debfc3dSmrg _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); 6941debfc3dSmrg _M_rep()->_M_dispose(__a); 6951debfc3dSmrg _M_data(__tmp); 6961debfc3dSmrg } 6971debfc3dSmrg return *this; 6981debfc3dSmrg } 6991debfc3dSmrg 7001debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 7011debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 7021debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 7031debfc3dSmrg assign(const _CharT* __s, size_type __n) 7041debfc3dSmrg { 7051debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 7061debfc3dSmrg _M_check_length(this->size(), __n, "basic_string::assign"); 7071debfc3dSmrg if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 7081debfc3dSmrg return _M_replace_safe(size_type(0), this->size(), __s, __n); 7091debfc3dSmrg else 7101debfc3dSmrg { 7111debfc3dSmrg // Work in-place. 7121debfc3dSmrg const size_type __pos = __s - _M_data(); 7131debfc3dSmrg if (__pos >= __n) 7141debfc3dSmrg _M_copy(_M_data(), __s, __n); 7151debfc3dSmrg else if (__pos) 7161debfc3dSmrg _M_move(_M_data(), __s, __n); 7171debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__n); 7181debfc3dSmrg return *this; 7191debfc3dSmrg } 7201debfc3dSmrg } 7211debfc3dSmrg 7221debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 7231debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 7241debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 7251debfc3dSmrg append(size_type __n, _CharT __c) 7261debfc3dSmrg { 7271debfc3dSmrg if (__n) 7281debfc3dSmrg { 7291debfc3dSmrg _M_check_length(size_type(0), __n, "basic_string::append"); 7301debfc3dSmrg const size_type __len = __n + this->size(); 7311debfc3dSmrg if (__len > this->capacity() || _M_rep()->_M_is_shared()) 7321debfc3dSmrg this->reserve(__len); 7331debfc3dSmrg _M_assign(_M_data() + this->size(), __n, __c); 7341debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__len); 7351debfc3dSmrg } 7361debfc3dSmrg return *this; 7371debfc3dSmrg } 7381debfc3dSmrg 7391debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 7401debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 7411debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 7421debfc3dSmrg append(const _CharT* __s, size_type __n) 7431debfc3dSmrg { 7441debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 7451debfc3dSmrg if (__n) 7461debfc3dSmrg { 7471debfc3dSmrg _M_check_length(size_type(0), __n, "basic_string::append"); 7481debfc3dSmrg const size_type __len = __n + this->size(); 7491debfc3dSmrg if (__len > this->capacity() || _M_rep()->_M_is_shared()) 7501debfc3dSmrg { 7511debfc3dSmrg if (_M_disjunct(__s)) 7521debfc3dSmrg this->reserve(__len); 7531debfc3dSmrg else 7541debfc3dSmrg { 7551debfc3dSmrg const size_type __off = __s - _M_data(); 7561debfc3dSmrg this->reserve(__len); 7571debfc3dSmrg __s = _M_data() + __off; 7581debfc3dSmrg } 7591debfc3dSmrg } 7601debfc3dSmrg _M_copy(_M_data() + this->size(), __s, __n); 7611debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__len); 7621debfc3dSmrg } 7631debfc3dSmrg return *this; 7641debfc3dSmrg } 7651debfc3dSmrg 7661debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 7671debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 7681debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 7691debfc3dSmrg append(const basic_string& __str) 7701debfc3dSmrg { 7711debfc3dSmrg const size_type __size = __str.size(); 7721debfc3dSmrg if (__size) 7731debfc3dSmrg { 7741debfc3dSmrg const size_type __len = __size + this->size(); 7751debfc3dSmrg if (__len > this->capacity() || _M_rep()->_M_is_shared()) 7761debfc3dSmrg this->reserve(__len); 7771debfc3dSmrg _M_copy(_M_data() + this->size(), __str._M_data(), __size); 7781debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__len); 7791debfc3dSmrg } 7801debfc3dSmrg return *this; 7811debfc3dSmrg } 7821debfc3dSmrg 7831debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 7841debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 7851debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 7861debfc3dSmrg append(const basic_string& __str, size_type __pos, size_type __n) 7871debfc3dSmrg { 7881debfc3dSmrg __str._M_check(__pos, "basic_string::append"); 7891debfc3dSmrg __n = __str._M_limit(__pos, __n); 7901debfc3dSmrg if (__n) 7911debfc3dSmrg { 7921debfc3dSmrg const size_type __len = __n + this->size(); 7931debfc3dSmrg if (__len > this->capacity() || _M_rep()->_M_is_shared()) 7941debfc3dSmrg this->reserve(__len); 7951debfc3dSmrg _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); 7961debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__len); 7971debfc3dSmrg } 7981debfc3dSmrg return *this; 7991debfc3dSmrg } 8001debfc3dSmrg 8011debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 8021debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 8031debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 8041debfc3dSmrg insert(size_type __pos, const _CharT* __s, size_type __n) 8051debfc3dSmrg { 8061debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 8071debfc3dSmrg _M_check(__pos, "basic_string::insert"); 8081debfc3dSmrg _M_check_length(size_type(0), __n, "basic_string::insert"); 8091debfc3dSmrg if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 8101debfc3dSmrg return _M_replace_safe(__pos, size_type(0), __s, __n); 8111debfc3dSmrg else 8121debfc3dSmrg { 8131debfc3dSmrg // Work in-place. 8141debfc3dSmrg const size_type __off = __s - _M_data(); 8151debfc3dSmrg _M_mutate(__pos, 0, __n); 8161debfc3dSmrg __s = _M_data() + __off; 8171debfc3dSmrg _CharT* __p = _M_data() + __pos; 8181debfc3dSmrg if (__s + __n <= __p) 8191debfc3dSmrg _M_copy(__p, __s, __n); 8201debfc3dSmrg else if (__s >= __p) 8211debfc3dSmrg _M_copy(__p, __s + __n, __n); 8221debfc3dSmrg else 8231debfc3dSmrg { 8241debfc3dSmrg const size_type __nleft = __p - __s; 8251debfc3dSmrg _M_copy(__p, __s, __nleft); 8261debfc3dSmrg _M_copy(__p + __nleft, __p + __n, __n - __nleft); 8271debfc3dSmrg } 8281debfc3dSmrg return *this; 8291debfc3dSmrg } 8301debfc3dSmrg } 8311debfc3dSmrg 8321debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 8331debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::iterator 8341debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 8351debfc3dSmrg erase(iterator __first, iterator __last) 8361debfc3dSmrg { 8371debfc3dSmrg _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last 8381debfc3dSmrg && __last <= _M_iend()); 8391debfc3dSmrg 8401debfc3dSmrg // NB: This isn't just an optimization (bail out early when 8411debfc3dSmrg // there is nothing to do, really), it's also a correctness 8421debfc3dSmrg // issue vs MT, see libstdc++/40518. 8431debfc3dSmrg const size_type __size = __last - __first; 8441debfc3dSmrg if (__size) 8451debfc3dSmrg { 8461debfc3dSmrg const size_type __pos = __first - _M_ibegin(); 8471debfc3dSmrg _M_mutate(__pos, __size, size_type(0)); 8481debfc3dSmrg _M_rep()->_M_set_leaked(); 8491debfc3dSmrg return iterator(_M_data() + __pos); 8501debfc3dSmrg } 8511debfc3dSmrg else 8521debfc3dSmrg return __first; 8531debfc3dSmrg } 8541debfc3dSmrg 8551debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 8561debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 8571debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 8581debfc3dSmrg replace(size_type __pos, size_type __n1, const _CharT* __s, 8591debfc3dSmrg size_type __n2) 8601debfc3dSmrg { 8611debfc3dSmrg __glibcxx_requires_string_len(__s, __n2); 8621debfc3dSmrg _M_check(__pos, "basic_string::replace"); 8631debfc3dSmrg __n1 = _M_limit(__pos, __n1); 8641debfc3dSmrg _M_check_length(__n1, __n2, "basic_string::replace"); 8651debfc3dSmrg bool __left; 8661debfc3dSmrg if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 8671debfc3dSmrg return _M_replace_safe(__pos, __n1, __s, __n2); 8681debfc3dSmrg else if ((__left = __s + __n2 <= _M_data() + __pos) 8691debfc3dSmrg || _M_data() + __pos + __n1 <= __s) 8701debfc3dSmrg { 8711debfc3dSmrg // Work in-place: non-overlapping case. 8721debfc3dSmrg size_type __off = __s - _M_data(); 8731debfc3dSmrg __left ? __off : (__off += __n2 - __n1); 8741debfc3dSmrg _M_mutate(__pos, __n1, __n2); 8751debfc3dSmrg _M_copy(_M_data() + __pos, _M_data() + __off, __n2); 8761debfc3dSmrg return *this; 8771debfc3dSmrg } 8781debfc3dSmrg else 8791debfc3dSmrg { 8801debfc3dSmrg // Todo: overlapping case. 8811debfc3dSmrg const basic_string __tmp(__s, __n2); 8821debfc3dSmrg return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); 8831debfc3dSmrg } 8841debfc3dSmrg } 8851debfc3dSmrg 8861debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 8871debfc3dSmrg void 8881debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::_Rep:: 8891debfc3dSmrg _M_destroy(const _Alloc& __a) throw () 8901debfc3dSmrg { 8911debfc3dSmrg const size_type __size = sizeof(_Rep_base) + 8921debfc3dSmrg (this->_M_capacity + 1) * sizeof(_CharT); 8931debfc3dSmrg _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); 8941debfc3dSmrg } 8951debfc3dSmrg 8961debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 8971debfc3dSmrg void 8981debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 8991debfc3dSmrg _M_leak_hard() 9001debfc3dSmrg { 9011debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 9021debfc3dSmrg if (_M_rep() == &_S_empty_rep()) 9031debfc3dSmrg return; 9041debfc3dSmrg #endif 9051debfc3dSmrg if (_M_rep()->_M_is_shared()) 9061debfc3dSmrg _M_mutate(0, 0, 0); 9071debfc3dSmrg _M_rep()->_M_set_leaked(); 9081debfc3dSmrg } 9091debfc3dSmrg 9101debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 9111debfc3dSmrg void 9121debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 9131debfc3dSmrg _M_mutate(size_type __pos, size_type __len1, size_type __len2) 9141debfc3dSmrg { 9151debfc3dSmrg const size_type __old_size = this->size(); 9161debfc3dSmrg const size_type __new_size = __old_size + __len2 - __len1; 9171debfc3dSmrg const size_type __how_much = __old_size - __pos - __len1; 9181debfc3dSmrg 9191debfc3dSmrg if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) 9201debfc3dSmrg { 9211debfc3dSmrg // Must reallocate. 9221debfc3dSmrg const allocator_type __a = get_allocator(); 9231debfc3dSmrg _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); 9241debfc3dSmrg 9251debfc3dSmrg if (__pos) 9261debfc3dSmrg _M_copy(__r->_M_refdata(), _M_data(), __pos); 9271debfc3dSmrg if (__how_much) 9281debfc3dSmrg _M_copy(__r->_M_refdata() + __pos + __len2, 9291debfc3dSmrg _M_data() + __pos + __len1, __how_much); 9301debfc3dSmrg 9311debfc3dSmrg _M_rep()->_M_dispose(__a); 9321debfc3dSmrg _M_data(__r->_M_refdata()); 9331debfc3dSmrg } 9341debfc3dSmrg else if (__how_much && __len1 != __len2) 9351debfc3dSmrg { 9361debfc3dSmrg // Work in-place. 9371debfc3dSmrg _M_move(_M_data() + __pos + __len2, 9381debfc3dSmrg _M_data() + __pos + __len1, __how_much); 9391debfc3dSmrg } 9401debfc3dSmrg _M_rep()->_M_set_length_and_sharable(__new_size); 9411debfc3dSmrg } 9421debfc3dSmrg 9431debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 9441debfc3dSmrg void 9451debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 9461debfc3dSmrg reserve(size_type __res) 9471debfc3dSmrg { 9481debfc3dSmrg if (__res != this->capacity() || _M_rep()->_M_is_shared()) 9491debfc3dSmrg { 9501debfc3dSmrg // Make sure we don't shrink below the current size 9511debfc3dSmrg if (__res < this->size()) 9521debfc3dSmrg __res = this->size(); 9531debfc3dSmrg const allocator_type __a = get_allocator(); 9541debfc3dSmrg _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); 9551debfc3dSmrg _M_rep()->_M_dispose(__a); 9561debfc3dSmrg _M_data(__tmp); 9571debfc3dSmrg } 9581debfc3dSmrg } 9591debfc3dSmrg 9601debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 9611debfc3dSmrg void 9621debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 9631debfc3dSmrg swap(basic_string& __s) 964c0a68be4Smrg _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value) 9651debfc3dSmrg { 9661debfc3dSmrg if (_M_rep()->_M_is_leaked()) 9671debfc3dSmrg _M_rep()->_M_set_sharable(); 9681debfc3dSmrg if (__s._M_rep()->_M_is_leaked()) 9691debfc3dSmrg __s._M_rep()->_M_set_sharable(); 9701debfc3dSmrg if (this->get_allocator() == __s.get_allocator()) 9711debfc3dSmrg { 9721debfc3dSmrg _CharT* __tmp = _M_data(); 9731debfc3dSmrg _M_data(__s._M_data()); 9741debfc3dSmrg __s._M_data(__tmp); 9751debfc3dSmrg } 9761debfc3dSmrg // The code below can usually be optimized away. 9771debfc3dSmrg else 9781debfc3dSmrg { 9791debfc3dSmrg const basic_string __tmp1(_M_ibegin(), _M_iend(), 9801debfc3dSmrg __s.get_allocator()); 9811debfc3dSmrg const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 9821debfc3dSmrg this->get_allocator()); 9831debfc3dSmrg *this = __tmp2; 9841debfc3dSmrg __s = __tmp1; 9851debfc3dSmrg } 9861debfc3dSmrg } 9871debfc3dSmrg 9881debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 9891debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::_Rep* 9901debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::_Rep:: 9911debfc3dSmrg _S_create(size_type __capacity, size_type __old_capacity, 9921debfc3dSmrg const _Alloc& __alloc) 9931debfc3dSmrg { 9941debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 9951debfc3dSmrg // 83. String::npos vs. string::max_size() 9961debfc3dSmrg if (__capacity > _S_max_size) 9971debfc3dSmrg __throw_length_error(__N("basic_string::_S_create")); 9981debfc3dSmrg 9991debfc3dSmrg // The standard places no restriction on allocating more memory 10001debfc3dSmrg // than is strictly needed within this layer at the moment or as 10011debfc3dSmrg // requested by an explicit application call to reserve(). 10021debfc3dSmrg 10031debfc3dSmrg // Many malloc implementations perform quite poorly when an 10041debfc3dSmrg // application attempts to allocate memory in a stepwise fashion 10051debfc3dSmrg // growing each allocation size by only 1 char. Additionally, 10061debfc3dSmrg // it makes little sense to allocate less linear memory than the 10071debfc3dSmrg // natural blocking size of the malloc implementation. 10081debfc3dSmrg // Unfortunately, we would need a somewhat low-level calculation 10091debfc3dSmrg // with tuned parameters to get this perfect for any particular 10101debfc3dSmrg // malloc implementation. Fortunately, generalizations about 10111debfc3dSmrg // common features seen among implementations seems to suffice. 10121debfc3dSmrg 10131debfc3dSmrg // __pagesize need not match the actual VM page size for good 10141debfc3dSmrg // results in practice, thus we pick a common value on the low 10151debfc3dSmrg // side. __malloc_header_size is an estimate of the amount of 10161debfc3dSmrg // overhead per memory allocation (in practice seen N * sizeof 10171debfc3dSmrg // (void*) where N is 0, 2 or 4). According to folklore, 10181debfc3dSmrg // picking this value on the high side is better than 10191debfc3dSmrg // low-balling it (especially when this algorithm is used with 10201debfc3dSmrg // malloc implementations that allocate memory blocks rounded up 10211debfc3dSmrg // to a size which is a power of 2). 10221debfc3dSmrg const size_type __pagesize = 4096; 10231debfc3dSmrg const size_type __malloc_header_size = 4 * sizeof(void*); 10241debfc3dSmrg 10251debfc3dSmrg // The below implements an exponential growth policy, necessary to 10261debfc3dSmrg // meet amortized linear time requirements of the library: see 10271debfc3dSmrg // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 10281debfc3dSmrg // It's active for allocations requiring an amount of memory above 10291debfc3dSmrg // system pagesize. This is consistent with the requirements of the 10301debfc3dSmrg // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html 10311debfc3dSmrg if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 10321debfc3dSmrg __capacity = 2 * __old_capacity; 10331debfc3dSmrg 10341debfc3dSmrg // NB: Need an array of char_type[__capacity], plus a terminating 10351debfc3dSmrg // null char_type() element, plus enough for the _Rep data structure. 10361debfc3dSmrg // Whew. Seemingly so needy, yet so elemental. 10371debfc3dSmrg size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 10381debfc3dSmrg 10391debfc3dSmrg const size_type __adj_size = __size + __malloc_header_size; 10401debfc3dSmrg if (__adj_size > __pagesize && __capacity > __old_capacity) 10411debfc3dSmrg { 10421debfc3dSmrg const size_type __extra = __pagesize - __adj_size % __pagesize; 10431debfc3dSmrg __capacity += __extra / sizeof(_CharT); 10441debfc3dSmrg // Never allocate a string bigger than _S_max_size. 10451debfc3dSmrg if (__capacity > _S_max_size) 10461debfc3dSmrg __capacity = _S_max_size; 10471debfc3dSmrg __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 10481debfc3dSmrg } 10491debfc3dSmrg 10501debfc3dSmrg // NB: Might throw, but no worries about a leak, mate: _Rep() 10511debfc3dSmrg // does not throw. 10521debfc3dSmrg void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); 10531debfc3dSmrg _Rep *__p = new (__place) _Rep; 10541debfc3dSmrg __p->_M_capacity = __capacity; 10551debfc3dSmrg // ABI compatibility - 3.4.x set in _S_create both 10561debfc3dSmrg // _M_refcount and _M_length. All callers of _S_create 10571debfc3dSmrg // in basic_string.tcc then set just _M_length. 10581debfc3dSmrg // In 4.0.x and later both _M_refcount and _M_length 10591debfc3dSmrg // are initialized in the callers, unfortunately we can 10601debfc3dSmrg // have 3.4.x compiled code with _S_create callers inlined 10611debfc3dSmrg // calling 4.0.x+ _S_create. 10621debfc3dSmrg __p->_M_set_sharable(); 10631debfc3dSmrg return __p; 10641debfc3dSmrg } 10651debfc3dSmrg 10661debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 10671debfc3dSmrg _CharT* 10681debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>::_Rep:: 10691debfc3dSmrg _M_clone(const _Alloc& __alloc, size_type __res) 10701debfc3dSmrg { 10711debfc3dSmrg // Requested capacity of the clone. 10721debfc3dSmrg const size_type __requested_cap = this->_M_length + __res; 10731debfc3dSmrg _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, 10741debfc3dSmrg __alloc); 10751debfc3dSmrg if (this->_M_length) 10761debfc3dSmrg _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); 10771debfc3dSmrg 10781debfc3dSmrg __r->_M_set_length_and_sharable(this->_M_length); 10791debfc3dSmrg return __r->_M_refdata(); 10801debfc3dSmrg } 10811debfc3dSmrg 10821debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 10831debfc3dSmrg void 10841debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 10851debfc3dSmrg resize(size_type __n, _CharT __c) 10861debfc3dSmrg { 10871debfc3dSmrg const size_type __size = this->size(); 10881debfc3dSmrg _M_check_length(__size, __n, "basic_string::resize"); 10891debfc3dSmrg if (__size < __n) 10901debfc3dSmrg this->append(__n - __size, __c); 10911debfc3dSmrg else if (__n < __size) 10921debfc3dSmrg this->erase(__n); 10931debfc3dSmrg // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) 10941debfc3dSmrg } 10951debfc3dSmrg 10961debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 10971debfc3dSmrg template<typename _InputIterator> 10981debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 10991debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 11001debfc3dSmrg _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 11011debfc3dSmrg _InputIterator __k2, __false_type) 11021debfc3dSmrg { 11031debfc3dSmrg const basic_string __s(__k1, __k2); 11041debfc3dSmrg const size_type __n1 = __i2 - __i1; 11051debfc3dSmrg _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); 11061debfc3dSmrg return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), 11071debfc3dSmrg __s.size()); 11081debfc3dSmrg } 11091debfc3dSmrg 11101debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11111debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 11121debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 11131debfc3dSmrg _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 11141debfc3dSmrg _CharT __c) 11151debfc3dSmrg { 11161debfc3dSmrg _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 11171debfc3dSmrg _M_mutate(__pos1, __n1, __n2); 11181debfc3dSmrg if (__n2) 11191debfc3dSmrg _M_assign(_M_data() + __pos1, __n2, __c); 11201debfc3dSmrg return *this; 11211debfc3dSmrg } 11221debfc3dSmrg 11231debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11241debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& 11251debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 11261debfc3dSmrg _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, 11271debfc3dSmrg size_type __n2) 11281debfc3dSmrg { 11291debfc3dSmrg _M_mutate(__pos1, __n1, __n2); 11301debfc3dSmrg if (__n2) 11311debfc3dSmrg _M_copy(_M_data() + __pos1, __s, __n2); 11321debfc3dSmrg return *this; 11331debfc3dSmrg } 11341debfc3dSmrg 11351debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11361debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 11371debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: 11381debfc3dSmrg copy(_CharT* __s, size_type __n, size_type __pos) const 11391debfc3dSmrg { 11401debfc3dSmrg _M_check(__pos, "basic_string::copy"); 11411debfc3dSmrg __n = _M_limit(__pos, __n); 11421debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 11431debfc3dSmrg if (__n) 11441debfc3dSmrg _M_copy(__s, _M_data() + __pos, __n); 11451debfc3dSmrg // 21.3.5.7 par 3: do not append null. (good.) 11461debfc3dSmrg return __n; 11471debfc3dSmrg } 11481debfc3dSmrg #endif // !_GLIBCXX_USE_CXX11_ABI 11491debfc3dSmrg 11501debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11511debfc3dSmrg basic_string<_CharT, _Traits, _Alloc> operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)11521debfc3dSmrg operator+(const _CharT* __lhs, 11531debfc3dSmrg const basic_string<_CharT, _Traits, _Alloc>& __rhs) 11541debfc3dSmrg { 11551debfc3dSmrg __glibcxx_requires_string(__lhs); 11561debfc3dSmrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 11571debfc3dSmrg typedef typename __string_type::size_type __size_type; 1158*8feb0f0bSmrg typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 1159*8feb0f0bSmrg rebind<_CharT>::other _Char_alloc_type; 1160*8feb0f0bSmrg typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; 11611debfc3dSmrg const __size_type __len = _Traits::length(__lhs); 1162*8feb0f0bSmrg __string_type __str(_Alloc_traits::_S_select_on_copy( 1163*8feb0f0bSmrg __rhs.get_allocator())); 11641debfc3dSmrg __str.reserve(__len + __rhs.size()); 11651debfc3dSmrg __str.append(__lhs, __len); 11661debfc3dSmrg __str.append(__rhs); 11671debfc3dSmrg return __str; 11681debfc3dSmrg } 11691debfc3dSmrg 11701debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11711debfc3dSmrg basic_string<_CharT, _Traits, _Alloc> operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)11721debfc3dSmrg operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) 11731debfc3dSmrg { 11741debfc3dSmrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 11751debfc3dSmrg typedef typename __string_type::size_type __size_type; 1176*8feb0f0bSmrg typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 1177*8feb0f0bSmrg rebind<_CharT>::other _Char_alloc_type; 1178*8feb0f0bSmrg typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; 1179*8feb0f0bSmrg __string_type __str(_Alloc_traits::_S_select_on_copy( 1180*8feb0f0bSmrg __rhs.get_allocator())); 11811debfc3dSmrg const __size_type __len = __rhs.size(); 11821debfc3dSmrg __str.reserve(__len + 1); 11831debfc3dSmrg __str.append(__size_type(1), __lhs); 11841debfc3dSmrg __str.append(__rhs); 11851debfc3dSmrg return __str; 11861debfc3dSmrg } 11871debfc3dSmrg 11881debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 11891debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 11901debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT * __s,size_type __pos,size_type __n) const11911debfc3dSmrg find(const _CharT* __s, size_type __pos, size_type __n) const 11921debfc3dSmrg _GLIBCXX_NOEXCEPT 11931debfc3dSmrg { 11941debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 11951debfc3dSmrg const size_type __size = this->size(); 11961debfc3dSmrg 11971debfc3dSmrg if (__n == 0) 11981debfc3dSmrg return __pos <= __size ? __pos : npos; 11991debfc3dSmrg if (__pos >= __size) 12001debfc3dSmrg return npos; 12011debfc3dSmrg 12021debfc3dSmrg const _CharT __elem0 = __s[0]; 12031debfc3dSmrg const _CharT* const __data = data(); 12041debfc3dSmrg const _CharT* __first = __data + __pos; 12051debfc3dSmrg const _CharT* const __last = __data + __size; 12061debfc3dSmrg size_type __len = __size - __pos; 12071debfc3dSmrg 12081debfc3dSmrg while (__len >= __n) 12091debfc3dSmrg { 12101debfc3dSmrg // Find the first occurrence of __elem0: 12111debfc3dSmrg __first = traits_type::find(__first, __len - __n + 1, __elem0); 12121debfc3dSmrg if (!__first) 12131debfc3dSmrg return npos; 12141debfc3dSmrg // Compare the full strings from the first occurrence of __elem0. 12151debfc3dSmrg // We already know that __first[0] == __s[0] but compare them again 12161debfc3dSmrg // anyway because __s is probably aligned, which helps memcmp. 12171debfc3dSmrg if (traits_type::compare(__first, __s, __n) == 0) 12181debfc3dSmrg return __first - __data; 12191debfc3dSmrg __len = __last - ++__first; 12201debfc3dSmrg } 12211debfc3dSmrg return npos; 12221debfc3dSmrg } 12231debfc3dSmrg 12241debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 12251debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 12261debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find(_CharT __c,size_type __pos) const12271debfc3dSmrg find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 12281debfc3dSmrg { 12291debfc3dSmrg size_type __ret = npos; 12301debfc3dSmrg const size_type __size = this->size(); 12311debfc3dSmrg if (__pos < __size) 12321debfc3dSmrg { 12331debfc3dSmrg const _CharT* __data = _M_data(); 12341debfc3dSmrg const size_type __n = __size - __pos; 12351debfc3dSmrg const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 12361debfc3dSmrg if (__p) 12371debfc3dSmrg __ret = __p - __data; 12381debfc3dSmrg } 12391debfc3dSmrg return __ret; 12401debfc3dSmrg } 12411debfc3dSmrg 12421debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 12431debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 12441debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT * __s,size_type __pos,size_type __n) const12451debfc3dSmrg rfind(const _CharT* __s, size_type __pos, size_type __n) const 12461debfc3dSmrg _GLIBCXX_NOEXCEPT 12471debfc3dSmrg { 12481debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 12491debfc3dSmrg const size_type __size = this->size(); 12501debfc3dSmrg if (__n <= __size) 12511debfc3dSmrg { 12521debfc3dSmrg __pos = std::min(size_type(__size - __n), __pos); 12531debfc3dSmrg const _CharT* __data = _M_data(); 12541debfc3dSmrg do 12551debfc3dSmrg { 12561debfc3dSmrg if (traits_type::compare(__data + __pos, __s, __n) == 0) 12571debfc3dSmrg return __pos; 12581debfc3dSmrg } 12591debfc3dSmrg while (__pos-- > 0); 12601debfc3dSmrg } 12611debfc3dSmrg return npos; 12621debfc3dSmrg } 12631debfc3dSmrg 12641debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 12651debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 12661debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: rfind(_CharT __c,size_type __pos) const12671debfc3dSmrg rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 12681debfc3dSmrg { 12691debfc3dSmrg size_type __size = this->size(); 12701debfc3dSmrg if (__size) 12711debfc3dSmrg { 12721debfc3dSmrg if (--__size > __pos) 12731debfc3dSmrg __size = __pos; 12741debfc3dSmrg for (++__size; __size-- > 0; ) 12751debfc3dSmrg if (traits_type::eq(_M_data()[__size], __c)) 12761debfc3dSmrg return __size; 12771debfc3dSmrg } 12781debfc3dSmrg return npos; 12791debfc3dSmrg } 12801debfc3dSmrg 12811debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 12821debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 12831debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT * __s,size_type __pos,size_type __n) const12841debfc3dSmrg find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 12851debfc3dSmrg _GLIBCXX_NOEXCEPT 12861debfc3dSmrg { 12871debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 12881debfc3dSmrg for (; __n && __pos < this->size(); ++__pos) 12891debfc3dSmrg { 12901debfc3dSmrg const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 12911debfc3dSmrg if (__p) 12921debfc3dSmrg return __pos; 12931debfc3dSmrg } 12941debfc3dSmrg return npos; 12951debfc3dSmrg } 12961debfc3dSmrg 12971debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 12981debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 12991debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT * __s,size_type __pos,size_type __n) const13001debfc3dSmrg find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 13011debfc3dSmrg _GLIBCXX_NOEXCEPT 13021debfc3dSmrg { 13031debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 13041debfc3dSmrg size_type __size = this->size(); 13051debfc3dSmrg if (__size && __n) 13061debfc3dSmrg { 13071debfc3dSmrg if (--__size > __pos) 13081debfc3dSmrg __size = __pos; 13091debfc3dSmrg do 13101debfc3dSmrg { 13111debfc3dSmrg if (traits_type::find(__s, __n, _M_data()[__size])) 13121debfc3dSmrg return __size; 13131debfc3dSmrg } 13141debfc3dSmrg while (__size-- != 0); 13151debfc3dSmrg } 13161debfc3dSmrg return npos; 13171debfc3dSmrg } 13181debfc3dSmrg 13191debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 13201debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 13211debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const13221debfc3dSmrg find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 13231debfc3dSmrg _GLIBCXX_NOEXCEPT 13241debfc3dSmrg { 13251debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 13261debfc3dSmrg for (; __pos < this->size(); ++__pos) 13271debfc3dSmrg if (!traits_type::find(__s, __n, _M_data()[__pos])) 13281debfc3dSmrg return __pos; 13291debfc3dSmrg return npos; 13301debfc3dSmrg } 13311debfc3dSmrg 13321debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 13331debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 13341debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(_CharT __c,size_type __pos) const13351debfc3dSmrg find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 13361debfc3dSmrg { 13371debfc3dSmrg for (; __pos < this->size(); ++__pos) 13381debfc3dSmrg if (!traits_type::eq(_M_data()[__pos], __c)) 13391debfc3dSmrg return __pos; 13401debfc3dSmrg return npos; 13411debfc3dSmrg } 13421debfc3dSmrg 13431debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 13441debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 13451debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const13461debfc3dSmrg find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 13471debfc3dSmrg _GLIBCXX_NOEXCEPT 13481debfc3dSmrg { 13491debfc3dSmrg __glibcxx_requires_string_len(__s, __n); 13501debfc3dSmrg size_type __size = this->size(); 13511debfc3dSmrg if (__size) 13521debfc3dSmrg { 13531debfc3dSmrg if (--__size > __pos) 13541debfc3dSmrg __size = __pos; 13551debfc3dSmrg do 13561debfc3dSmrg { 13571debfc3dSmrg if (!traits_type::find(__s, __n, _M_data()[__size])) 13581debfc3dSmrg return __size; 13591debfc3dSmrg } 13601debfc3dSmrg while (__size--); 13611debfc3dSmrg } 13621debfc3dSmrg return npos; 13631debfc3dSmrg } 13641debfc3dSmrg 13651debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 13661debfc3dSmrg typename basic_string<_CharT, _Traits, _Alloc>::size_type 13671debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(_CharT __c,size_type __pos) const13681debfc3dSmrg find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 13691debfc3dSmrg { 13701debfc3dSmrg size_type __size = this->size(); 13711debfc3dSmrg if (__size) 13721debfc3dSmrg { 13731debfc3dSmrg if (--__size > __pos) 13741debfc3dSmrg __size = __pos; 13751debfc3dSmrg do 13761debfc3dSmrg { 13771debfc3dSmrg if (!traits_type::eq(_M_data()[__size], __c)) 13781debfc3dSmrg return __size; 13791debfc3dSmrg } 13801debfc3dSmrg while (__size--); 13811debfc3dSmrg } 13821debfc3dSmrg return npos; 13831debfc3dSmrg } 13841debfc3dSmrg 13851debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 13861debfc3dSmrg int 13871debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n,const basic_string & __str) const13881debfc3dSmrg compare(size_type __pos, size_type __n, const basic_string& __str) const 13891debfc3dSmrg { 13901debfc3dSmrg _M_check(__pos, "basic_string::compare"); 13911debfc3dSmrg __n = _M_limit(__pos, __n); 13921debfc3dSmrg const size_type __osize = __str.size(); 13931debfc3dSmrg const size_type __len = std::min(__n, __osize); 13941debfc3dSmrg int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 13951debfc3dSmrg if (!__r) 13961debfc3dSmrg __r = _S_compare(__n, __osize); 13971debfc3dSmrg return __r; 13981debfc3dSmrg } 13991debfc3dSmrg 14001debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 14011debfc3dSmrg int 14021debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const14031debfc3dSmrg compare(size_type __pos1, size_type __n1, const basic_string& __str, 14041debfc3dSmrg size_type __pos2, size_type __n2) const 14051debfc3dSmrg { 14061debfc3dSmrg _M_check(__pos1, "basic_string::compare"); 14071debfc3dSmrg __str._M_check(__pos2, "basic_string::compare"); 14081debfc3dSmrg __n1 = _M_limit(__pos1, __n1); 14091debfc3dSmrg __n2 = __str._M_limit(__pos2, __n2); 14101debfc3dSmrg const size_type __len = std::min(__n1, __n2); 14111debfc3dSmrg int __r = traits_type::compare(_M_data() + __pos1, 14121debfc3dSmrg __str.data() + __pos2, __len); 14131debfc3dSmrg if (!__r) 14141debfc3dSmrg __r = _S_compare(__n1, __n2); 14151debfc3dSmrg return __r; 14161debfc3dSmrg } 14171debfc3dSmrg 14181debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 14191debfc3dSmrg int 14201debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT * __s) const14211debfc3dSmrg compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT 14221debfc3dSmrg { 14231debfc3dSmrg __glibcxx_requires_string(__s); 14241debfc3dSmrg const size_type __size = this->size(); 14251debfc3dSmrg const size_type __osize = traits_type::length(__s); 14261debfc3dSmrg const size_type __len = std::min(__size, __osize); 14271debfc3dSmrg int __r = traits_type::compare(_M_data(), __s, __len); 14281debfc3dSmrg if (!__r) 14291debfc3dSmrg __r = _S_compare(__size, __osize); 14301debfc3dSmrg return __r; 14311debfc3dSmrg } 14321debfc3dSmrg 14331debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 14341debfc3dSmrg int 14351debfc3dSmrg basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s) const14361debfc3dSmrg compare(size_type __pos, size_type __n1, const _CharT* __s) const 14371debfc3dSmrg { 14381debfc3dSmrg __glibcxx_requires_string(__s); 14391debfc3dSmrg _M_check(__pos, "basic_string::compare"); 14401debfc3dSmrg __n1 = _M_limit(__pos, __n1); 14411debfc3dSmrg const size_type __osize = traits_type::length(__s); 14421debfc3dSmrg const size_type __len = std::min(__n1, __osize); 14431debfc3dSmrg int __r = traits_type::compare(_M_data() + __pos, __s, __len); 14441debfc3dSmrg if (!__r) 14451debfc3dSmrg __r = _S_compare(__n1, __osize); 14461debfc3dSmrg return __r; 14471debfc3dSmrg } 14481debfc3dSmrg 14491debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 14501debfc3dSmrg int 14511debfc3dSmrg basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const14521debfc3dSmrg compare(size_type __pos, size_type __n1, const _CharT* __s, 14531debfc3dSmrg size_type __n2) const 14541debfc3dSmrg { 14551debfc3dSmrg __glibcxx_requires_string_len(__s, __n2); 14561debfc3dSmrg _M_check(__pos, "basic_string::compare"); 14571debfc3dSmrg __n1 = _M_limit(__pos, __n1); 14581debfc3dSmrg const size_type __len = std::min(__n1, __n2); 14591debfc3dSmrg int __r = traits_type::compare(_M_data() + __pos, __s, __len); 14601debfc3dSmrg if (!__r) 14611debfc3dSmrg __r = _S_compare(__n1, __n2); 14621debfc3dSmrg return __r; 14631debfc3dSmrg } 14641debfc3dSmrg 14651debfc3dSmrg // 21.3.7.9 basic_string::getline and operators 14661debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 14671debfc3dSmrg basic_istream<_CharT, _Traits>& operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)14681debfc3dSmrg operator>>(basic_istream<_CharT, _Traits>& __in, 14691debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& __str) 14701debfc3dSmrg { 14711debfc3dSmrg typedef basic_istream<_CharT, _Traits> __istream_type; 14721debfc3dSmrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 14731debfc3dSmrg typedef typename __istream_type::ios_base __ios_base; 14741debfc3dSmrg typedef typename __istream_type::int_type __int_type; 14751debfc3dSmrg typedef typename __string_type::size_type __size_type; 14761debfc3dSmrg typedef ctype<_CharT> __ctype_type; 14771debfc3dSmrg typedef typename __ctype_type::ctype_base __ctype_base; 14781debfc3dSmrg 14791debfc3dSmrg __size_type __extracted = 0; 14801debfc3dSmrg typename __ios_base::iostate __err = __ios_base::goodbit; 14811debfc3dSmrg typename __istream_type::sentry __cerb(__in, false); 14821debfc3dSmrg if (__cerb) 14831debfc3dSmrg { 14841debfc3dSmrg __try 14851debfc3dSmrg { 14861debfc3dSmrg // Avoid reallocation for common case. 14871debfc3dSmrg __str.erase(); 14881debfc3dSmrg _CharT __buf[128]; 14891debfc3dSmrg __size_type __len = 0; 14901debfc3dSmrg const streamsize __w = __in.width(); 14911debfc3dSmrg const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 14921debfc3dSmrg : __str.max_size(); 14931debfc3dSmrg const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 14941debfc3dSmrg const __int_type __eof = _Traits::eof(); 14951debfc3dSmrg __int_type __c = __in.rdbuf()->sgetc(); 14961debfc3dSmrg 14971debfc3dSmrg while (__extracted < __n 14981debfc3dSmrg && !_Traits::eq_int_type(__c, __eof) 14991debfc3dSmrg && !__ct.is(__ctype_base::space, 15001debfc3dSmrg _Traits::to_char_type(__c))) 15011debfc3dSmrg { 15021debfc3dSmrg if (__len == sizeof(__buf) / sizeof(_CharT)) 15031debfc3dSmrg { 15041debfc3dSmrg __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 15051debfc3dSmrg __len = 0; 15061debfc3dSmrg } 15071debfc3dSmrg __buf[__len++] = _Traits::to_char_type(__c); 15081debfc3dSmrg ++__extracted; 15091debfc3dSmrg __c = __in.rdbuf()->snextc(); 15101debfc3dSmrg } 15111debfc3dSmrg __str.append(__buf, __len); 15121debfc3dSmrg 15131debfc3dSmrg if (_Traits::eq_int_type(__c, __eof)) 15141debfc3dSmrg __err |= __ios_base::eofbit; 15151debfc3dSmrg __in.width(0); 15161debfc3dSmrg } 15171debfc3dSmrg __catch(__cxxabiv1::__forced_unwind&) 15181debfc3dSmrg { 15191debfc3dSmrg __in._M_setstate(__ios_base::badbit); 15201debfc3dSmrg __throw_exception_again; 15211debfc3dSmrg } 15221debfc3dSmrg __catch(...) 15231debfc3dSmrg { 15241debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 15251debfc3dSmrg // 91. Description of operator>> and getline() for string<> 15261debfc3dSmrg // might cause endless loop 15271debfc3dSmrg __in._M_setstate(__ios_base::badbit); 15281debfc3dSmrg } 15291debfc3dSmrg } 15301debfc3dSmrg // 211. operator>>(istream&, string&) doesn't set failbit 15311debfc3dSmrg if (!__extracted) 15321debfc3dSmrg __err |= __ios_base::failbit; 15331debfc3dSmrg if (__err) 15341debfc3dSmrg __in.setstate(__err); 15351debfc3dSmrg return __in; 15361debfc3dSmrg } 15371debfc3dSmrg 15381debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc> 15391debfc3dSmrg basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)15401debfc3dSmrg getline(basic_istream<_CharT, _Traits>& __in, 15411debfc3dSmrg basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 15421debfc3dSmrg { 15431debfc3dSmrg typedef basic_istream<_CharT, _Traits> __istream_type; 15441debfc3dSmrg typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 15451debfc3dSmrg typedef typename __istream_type::ios_base __ios_base; 15461debfc3dSmrg typedef typename __istream_type::int_type __int_type; 15471debfc3dSmrg typedef typename __string_type::size_type __size_type; 15481debfc3dSmrg 15491debfc3dSmrg __size_type __extracted = 0; 15501debfc3dSmrg const __size_type __n = __str.max_size(); 15511debfc3dSmrg typename __ios_base::iostate __err = __ios_base::goodbit; 15521debfc3dSmrg typename __istream_type::sentry __cerb(__in, true); 15531debfc3dSmrg if (__cerb) 15541debfc3dSmrg { 15551debfc3dSmrg __try 15561debfc3dSmrg { 15571debfc3dSmrg __str.erase(); 15581debfc3dSmrg const __int_type __idelim = _Traits::to_int_type(__delim); 15591debfc3dSmrg const __int_type __eof = _Traits::eof(); 15601debfc3dSmrg __int_type __c = __in.rdbuf()->sgetc(); 15611debfc3dSmrg 15621debfc3dSmrg while (__extracted < __n 15631debfc3dSmrg && !_Traits::eq_int_type(__c, __eof) 15641debfc3dSmrg && !_Traits::eq_int_type(__c, __idelim)) 15651debfc3dSmrg { 15661debfc3dSmrg __str += _Traits::to_char_type(__c); 15671debfc3dSmrg ++__extracted; 15681debfc3dSmrg __c = __in.rdbuf()->snextc(); 15691debfc3dSmrg } 15701debfc3dSmrg 15711debfc3dSmrg if (_Traits::eq_int_type(__c, __eof)) 15721debfc3dSmrg __err |= __ios_base::eofbit; 15731debfc3dSmrg else if (_Traits::eq_int_type(__c, __idelim)) 15741debfc3dSmrg { 15751debfc3dSmrg ++__extracted; 15761debfc3dSmrg __in.rdbuf()->sbumpc(); 15771debfc3dSmrg } 15781debfc3dSmrg else 15791debfc3dSmrg __err |= __ios_base::failbit; 15801debfc3dSmrg } 15811debfc3dSmrg __catch(__cxxabiv1::__forced_unwind&) 15821debfc3dSmrg { 15831debfc3dSmrg __in._M_setstate(__ios_base::badbit); 15841debfc3dSmrg __throw_exception_again; 15851debfc3dSmrg } 15861debfc3dSmrg __catch(...) 15871debfc3dSmrg { 15881debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 15891debfc3dSmrg // 91. Description of operator>> and getline() for string<> 15901debfc3dSmrg // might cause endless loop 15911debfc3dSmrg __in._M_setstate(__ios_base::badbit); 15921debfc3dSmrg } 15931debfc3dSmrg } 15941debfc3dSmrg if (!__extracted) 15951debfc3dSmrg __err |= __ios_base::failbit; 15961debfc3dSmrg if (__err) 15971debfc3dSmrg __in.setstate(__err); 15981debfc3dSmrg return __in; 15991debfc3dSmrg } 16001debfc3dSmrg 16011debfc3dSmrg // Inhibit implicit instantiations for required instantiations, 16021debfc3dSmrg // which are defined via explicit instantiations elsewhere. 16031debfc3dSmrg #if _GLIBCXX_EXTERN_TEMPLATE 1604*8feb0f0bSmrg // The explicit instantiation definitions in src/c++11/string-inst.cc and 1605*8feb0f0bSmrg // src/c++17/string-inst.cc only instantiate the members required for C++17 1606*8feb0f0bSmrg // and earlier standards (so not C++20's starts_with and ends_with). 1607*8feb0f0bSmrg // Suppress the explicit instantiation declarations for C++20, so C++20 1608*8feb0f0bSmrg // code will implicitly instantiate std::string and std::wstring as needed. 1609c0a68be4Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 16101debfc3dSmrg extern template class basic_string<char>; 16111debfc3dSmrg # elif ! _GLIBCXX_USE_CXX11_ABI 16121debfc3dSmrg // Still need to prevent implicit instantiation of the COW empty rep, 16131debfc3dSmrg // to ensure the definition in libstdc++.so is unique (PR 86138). 16141debfc3dSmrg extern template basic_string<char>::size_type 16151debfc3dSmrg basic_string<char>::_Rep::_S_empty_rep_storage[]; 16161debfc3dSmrg # endif 16171debfc3dSmrg 16181debfc3dSmrg extern template 16191debfc3dSmrg basic_istream<char>& 16201debfc3dSmrg operator>>(basic_istream<char>&, string&); 16211debfc3dSmrg extern template 16221debfc3dSmrg basic_ostream<char>& 16231debfc3dSmrg operator<<(basic_ostream<char>&, const string&); 16241debfc3dSmrg extern template 16251debfc3dSmrg basic_istream<char>& 16261debfc3dSmrg getline(basic_istream<char>&, string&, char); 16271debfc3dSmrg extern template 16281debfc3dSmrg basic_istream<char>& 16291debfc3dSmrg getline(basic_istream<char>&, string&); 16301debfc3dSmrg 16311debfc3dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 1632c0a68be4Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 16331debfc3dSmrg extern template class basic_string<wchar_t>; 16341debfc3dSmrg # elif ! _GLIBCXX_USE_CXX11_ABI 16351debfc3dSmrg extern template basic_string<wchar_t>::size_type 16361debfc3dSmrg basic_string<wchar_t>::_Rep::_S_empty_rep_storage[]; 16371debfc3dSmrg # endif 16381debfc3dSmrg 16391debfc3dSmrg extern template 16401debfc3dSmrg basic_istream<wchar_t>& 16411debfc3dSmrg operator>>(basic_istream<wchar_t>&, wstring&); 16421debfc3dSmrg extern template 16431debfc3dSmrg basic_ostream<wchar_t>& 16441debfc3dSmrg operator<<(basic_ostream<wchar_t>&, const wstring&); 16451debfc3dSmrg extern template 16461debfc3dSmrg basic_istream<wchar_t>& 16471debfc3dSmrg getline(basic_istream<wchar_t>&, wstring&, wchar_t); 16481debfc3dSmrg extern template 16491debfc3dSmrg basic_istream<wchar_t>& 16501debfc3dSmrg getline(basic_istream<wchar_t>&, wstring&); 16511debfc3dSmrg #endif // _GLIBCXX_USE_WCHAR_T 16521debfc3dSmrg #endif // _GLIBCXX_EXTERN_TEMPLATE 16531debfc3dSmrg 16541debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION 16551debfc3dSmrg } // namespace std 16561debfc3dSmrg 16571debfc3dSmrg #endif 1658