1*38fd1498Szrj // Components for manipulating sequences of characters -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file bits/basic_string.tcc 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{string} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj // 31*38fd1498Szrj // ISO C++ 14882: 21 Strings library 32*38fd1498Szrj // 33*38fd1498Szrj 34*38fd1498Szrj // Written by Jason Merrill based upon the specification by Takanori Adachi 35*38fd1498Szrj // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 36*38fd1498Szrj // Non-reference-counted implementation written by Paolo Carlini and 37*38fd1498Szrj // updated by Jonathan Wakely for ISO-14882-2011. 38*38fd1498Szrj 39*38fd1498Szrj #ifndef _BASIC_STRING_TCC 40*38fd1498Szrj #define _BASIC_STRING_TCC 1 41*38fd1498Szrj 42*38fd1498Szrj #pragma GCC system_header 43*38fd1498Szrj 44*38fd1498Szrj #include <bits/cxxabi_forced.h> 45*38fd1498Szrj 46*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 47*38fd1498Szrj { 48*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 49*38fd1498Szrj 50*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI 51*38fd1498Szrj 52*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 53*38fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 54*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::npos; 55*38fd1498Szrj 56*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 57*38fd1498Szrj void 58*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 59*38fd1498Szrj swap(basic_string& __s) _GLIBCXX_NOEXCEPT 60*38fd1498Szrj { 61*38fd1498Szrj if (this == &__s) 62*38fd1498Szrj return; 63*38fd1498Szrj 64*38fd1498Szrj _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); 65*38fd1498Szrj 66*38fd1498Szrj if (_M_is_local()) 67*38fd1498Szrj if (__s._M_is_local()) 68*38fd1498Szrj { 69*38fd1498Szrj if (length() && __s.length()) 70*38fd1498Szrj { 71*38fd1498Szrj _CharT __tmp_data[_S_local_capacity + 1]; 72*38fd1498Szrj traits_type::copy(__tmp_data, __s._M_local_buf, 73*38fd1498Szrj _S_local_capacity + 1); 74*38fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 75*38fd1498Szrj _S_local_capacity + 1); 76*38fd1498Szrj traits_type::copy(_M_local_buf, __tmp_data, 77*38fd1498Szrj _S_local_capacity + 1); 78*38fd1498Szrj } 79*38fd1498Szrj else if (__s.length()) 80*38fd1498Szrj { 81*38fd1498Szrj traits_type::copy(_M_local_buf, __s._M_local_buf, 82*38fd1498Szrj _S_local_capacity + 1); 83*38fd1498Szrj _M_length(__s.length()); 84*38fd1498Szrj __s._M_set_length(0); 85*38fd1498Szrj return; 86*38fd1498Szrj } 87*38fd1498Szrj else if (length()) 88*38fd1498Szrj { 89*38fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 90*38fd1498Szrj _S_local_capacity + 1); 91*38fd1498Szrj __s._M_length(length()); 92*38fd1498Szrj _M_set_length(0); 93*38fd1498Szrj return; 94*38fd1498Szrj } 95*38fd1498Szrj } 96*38fd1498Szrj else 97*38fd1498Szrj { 98*38fd1498Szrj const size_type __tmp_capacity = __s._M_allocated_capacity; 99*38fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 100*38fd1498Szrj _S_local_capacity + 1); 101*38fd1498Szrj _M_data(__s._M_data()); 102*38fd1498Szrj __s._M_data(__s._M_local_buf); 103*38fd1498Szrj _M_capacity(__tmp_capacity); 104*38fd1498Szrj } 105*38fd1498Szrj else 106*38fd1498Szrj { 107*38fd1498Szrj const size_type __tmp_capacity = _M_allocated_capacity; 108*38fd1498Szrj if (__s._M_is_local()) 109*38fd1498Szrj { 110*38fd1498Szrj traits_type::copy(_M_local_buf, __s._M_local_buf, 111*38fd1498Szrj _S_local_capacity + 1); 112*38fd1498Szrj __s._M_data(_M_data()); 113*38fd1498Szrj _M_data(_M_local_buf); 114*38fd1498Szrj } 115*38fd1498Szrj else 116*38fd1498Szrj { 117*38fd1498Szrj pointer __tmp_ptr = _M_data(); 118*38fd1498Szrj _M_data(__s._M_data()); 119*38fd1498Szrj __s._M_data(__tmp_ptr); 120*38fd1498Szrj _M_capacity(__s._M_allocated_capacity); 121*38fd1498Szrj } 122*38fd1498Szrj __s._M_capacity(__tmp_capacity); 123*38fd1498Szrj } 124*38fd1498Szrj 125*38fd1498Szrj const size_type __tmp_length = length(); 126*38fd1498Szrj _M_length(__s.length()); 127*38fd1498Szrj __s._M_length(__tmp_length); 128*38fd1498Szrj } 129*38fd1498Szrj 130*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 131*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::pointer 132*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 133*38fd1498Szrj _M_create(size_type& __capacity, size_type __old_capacity) 134*38fd1498Szrj { 135*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 136*38fd1498Szrj // 83. String::npos vs. string::max_size() 137*38fd1498Szrj if (__capacity > max_size()) 138*38fd1498Szrj std::__throw_length_error(__N("basic_string::_M_create")); 139*38fd1498Szrj 140*38fd1498Szrj // The below implements an exponential growth policy, necessary to 141*38fd1498Szrj // meet amortized linear time requirements of the library: see 142*38fd1498Szrj // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 143*38fd1498Szrj if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 144*38fd1498Szrj { 145*38fd1498Szrj __capacity = 2 * __old_capacity; 146*38fd1498Szrj // Never allocate a string bigger than max_size. 147*38fd1498Szrj if (__capacity > max_size()) 148*38fd1498Szrj __capacity = max_size(); 149*38fd1498Szrj } 150*38fd1498Szrj 151*38fd1498Szrj // NB: Need an array of char_type[__capacity], plus a terminating 152*38fd1498Szrj // null char_type() element. 153*38fd1498Szrj return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); 154*38fd1498Szrj } 155*38fd1498Szrj 156*38fd1498Szrj // NB: This is the special case for Input Iterators, used in 157*38fd1498Szrj // istreambuf_iterators, etc. 158*38fd1498Szrj // Input Iterators have a cost structure very different from 159*38fd1498Szrj // pointers, calling for a different coding style. 160*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 161*38fd1498Szrj template<typename _InIterator> 162*38fd1498Szrj void 163*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 164*38fd1498Szrj _M_construct(_InIterator __beg, _InIterator __end, 165*38fd1498Szrj std::input_iterator_tag) 166*38fd1498Szrj { 167*38fd1498Szrj size_type __len = 0; 168*38fd1498Szrj size_type __capacity = size_type(_S_local_capacity); 169*38fd1498Szrj 170*38fd1498Szrj while (__beg != __end && __len < __capacity) 171*38fd1498Szrj { 172*38fd1498Szrj _M_data()[__len++] = *__beg; 173*38fd1498Szrj ++__beg; 174*38fd1498Szrj } 175*38fd1498Szrj 176*38fd1498Szrj __try 177*38fd1498Szrj { 178*38fd1498Szrj while (__beg != __end) 179*38fd1498Szrj { 180*38fd1498Szrj if (__len == __capacity) 181*38fd1498Szrj { 182*38fd1498Szrj // Allocate more space. 183*38fd1498Szrj __capacity = __len + 1; 184*38fd1498Szrj pointer __another = _M_create(__capacity, __len); 185*38fd1498Szrj this->_S_copy(__another, _M_data(), __len); 186*38fd1498Szrj _M_dispose(); 187*38fd1498Szrj _M_data(__another); 188*38fd1498Szrj _M_capacity(__capacity); 189*38fd1498Szrj } 190*38fd1498Szrj _M_data()[__len++] = *__beg; 191*38fd1498Szrj ++__beg; 192*38fd1498Szrj } 193*38fd1498Szrj } 194*38fd1498Szrj __catch(...) 195*38fd1498Szrj { 196*38fd1498Szrj _M_dispose(); 197*38fd1498Szrj __throw_exception_again; 198*38fd1498Szrj } 199*38fd1498Szrj 200*38fd1498Szrj _M_set_length(__len); 201*38fd1498Szrj } 202*38fd1498Szrj 203*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 204*38fd1498Szrj template<typename _InIterator> 205*38fd1498Szrj void 206*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 207*38fd1498Szrj _M_construct(_InIterator __beg, _InIterator __end, 208*38fd1498Szrj std::forward_iterator_tag) 209*38fd1498Szrj { 210*38fd1498Szrj // NB: Not required, but considered best practice. 211*38fd1498Szrj if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 212*38fd1498Szrj std::__throw_logic_error(__N("basic_string::" 213*38fd1498Szrj "_M_construct null not valid")); 214*38fd1498Szrj 215*38fd1498Szrj size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); 216*38fd1498Szrj 217*38fd1498Szrj if (__dnew > size_type(_S_local_capacity)) 218*38fd1498Szrj { 219*38fd1498Szrj _M_data(_M_create(__dnew, size_type(0))); 220*38fd1498Szrj _M_capacity(__dnew); 221*38fd1498Szrj } 222*38fd1498Szrj 223*38fd1498Szrj // Check for out_of_range and length_error exceptions. 224*38fd1498Szrj __try 225*38fd1498Szrj { this->_S_copy_chars(_M_data(), __beg, __end); } 226*38fd1498Szrj __catch(...) 227*38fd1498Szrj { 228*38fd1498Szrj _M_dispose(); 229*38fd1498Szrj __throw_exception_again; 230*38fd1498Szrj } 231*38fd1498Szrj 232*38fd1498Szrj _M_set_length(__dnew); 233*38fd1498Szrj } 234*38fd1498Szrj 235*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 236*38fd1498Szrj void 237*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 238*38fd1498Szrj _M_construct(size_type __n, _CharT __c) 239*38fd1498Szrj { 240*38fd1498Szrj if (__n > size_type(_S_local_capacity)) 241*38fd1498Szrj { 242*38fd1498Szrj _M_data(_M_create(__n, size_type(0))); 243*38fd1498Szrj _M_capacity(__n); 244*38fd1498Szrj } 245*38fd1498Szrj 246*38fd1498Szrj if (__n) 247*38fd1498Szrj this->_S_assign(_M_data(), __n, __c); 248*38fd1498Szrj 249*38fd1498Szrj _M_set_length(__n); 250*38fd1498Szrj } 251*38fd1498Szrj 252*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 253*38fd1498Szrj void 254*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 255*38fd1498Szrj _M_assign(const basic_string& __str) 256*38fd1498Szrj { 257*38fd1498Szrj if (this != &__str) 258*38fd1498Szrj { 259*38fd1498Szrj const size_type __rsize = __str.length(); 260*38fd1498Szrj const size_type __capacity = capacity(); 261*38fd1498Szrj 262*38fd1498Szrj if (__rsize > __capacity) 263*38fd1498Szrj { 264*38fd1498Szrj size_type __new_capacity = __rsize; 265*38fd1498Szrj pointer __tmp = _M_create(__new_capacity, __capacity); 266*38fd1498Szrj _M_dispose(); 267*38fd1498Szrj _M_data(__tmp); 268*38fd1498Szrj _M_capacity(__new_capacity); 269*38fd1498Szrj } 270*38fd1498Szrj 271*38fd1498Szrj if (__rsize) 272*38fd1498Szrj this->_S_copy(_M_data(), __str._M_data(), __rsize); 273*38fd1498Szrj 274*38fd1498Szrj _M_set_length(__rsize); 275*38fd1498Szrj } 276*38fd1498Szrj } 277*38fd1498Szrj 278*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 279*38fd1498Szrj void 280*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 281*38fd1498Szrj reserve(size_type __res) 282*38fd1498Szrj { 283*38fd1498Szrj // Make sure we don't shrink below the current size. 284*38fd1498Szrj if (__res < length()) 285*38fd1498Szrj __res = length(); 286*38fd1498Szrj 287*38fd1498Szrj const size_type __capacity = capacity(); 288*38fd1498Szrj if (__res != __capacity) 289*38fd1498Szrj { 290*38fd1498Szrj if (__res > __capacity 291*38fd1498Szrj || __res > size_type(_S_local_capacity)) 292*38fd1498Szrj { 293*38fd1498Szrj pointer __tmp = _M_create(__res, __capacity); 294*38fd1498Szrj this->_S_copy(__tmp, _M_data(), length() + 1); 295*38fd1498Szrj _M_dispose(); 296*38fd1498Szrj _M_data(__tmp); 297*38fd1498Szrj _M_capacity(__res); 298*38fd1498Szrj } 299*38fd1498Szrj else if (!_M_is_local()) 300*38fd1498Szrj { 301*38fd1498Szrj this->_S_copy(_M_local_data(), _M_data(), length() + 1); 302*38fd1498Szrj _M_destroy(__capacity); 303*38fd1498Szrj _M_data(_M_local_data()); 304*38fd1498Szrj } 305*38fd1498Szrj } 306*38fd1498Szrj } 307*38fd1498Szrj 308*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 309*38fd1498Szrj void 310*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 311*38fd1498Szrj _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 312*38fd1498Szrj size_type __len2) 313*38fd1498Szrj { 314*38fd1498Szrj const size_type __how_much = length() - __pos - __len1; 315*38fd1498Szrj 316*38fd1498Szrj size_type __new_capacity = length() + __len2 - __len1; 317*38fd1498Szrj pointer __r = _M_create(__new_capacity, capacity()); 318*38fd1498Szrj 319*38fd1498Szrj if (__pos) 320*38fd1498Szrj this->_S_copy(__r, _M_data(), __pos); 321*38fd1498Szrj if (__s && __len2) 322*38fd1498Szrj this->_S_copy(__r + __pos, __s, __len2); 323*38fd1498Szrj if (__how_much) 324*38fd1498Szrj this->_S_copy(__r + __pos + __len2, 325*38fd1498Szrj _M_data() + __pos + __len1, __how_much); 326*38fd1498Szrj 327*38fd1498Szrj _M_dispose(); 328*38fd1498Szrj _M_data(__r); 329*38fd1498Szrj _M_capacity(__new_capacity); 330*38fd1498Szrj } 331*38fd1498Szrj 332*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 333*38fd1498Szrj void 334*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 335*38fd1498Szrj _M_erase(size_type __pos, size_type __n) 336*38fd1498Szrj { 337*38fd1498Szrj const size_type __how_much = length() - __pos - __n; 338*38fd1498Szrj 339*38fd1498Szrj if (__how_much && __n) 340*38fd1498Szrj this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); 341*38fd1498Szrj 342*38fd1498Szrj _M_set_length(length() - __n); 343*38fd1498Szrj } 344*38fd1498Szrj 345*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 346*38fd1498Szrj void 347*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 348*38fd1498Szrj resize(size_type __n, _CharT __c) 349*38fd1498Szrj { 350*38fd1498Szrj const size_type __size = this->size(); 351*38fd1498Szrj if (__size < __n) 352*38fd1498Szrj this->append(__n - __size, __c); 353*38fd1498Szrj else if (__n < __size) 354*38fd1498Szrj this->_M_set_length(__n); 355*38fd1498Szrj } 356*38fd1498Szrj 357*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 358*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 359*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 360*38fd1498Szrj _M_append(const _CharT* __s, size_type __n) 361*38fd1498Szrj { 362*38fd1498Szrj const size_type __len = __n + this->size(); 363*38fd1498Szrj 364*38fd1498Szrj if (__len <= this->capacity()) 365*38fd1498Szrj { 366*38fd1498Szrj if (__n) 367*38fd1498Szrj this->_S_copy(this->_M_data() + this->size(), __s, __n); 368*38fd1498Szrj } 369*38fd1498Szrj else 370*38fd1498Szrj this->_M_mutate(this->size(), size_type(0), __s, __n); 371*38fd1498Szrj 372*38fd1498Szrj this->_M_set_length(__len); 373*38fd1498Szrj return *this; 374*38fd1498Szrj } 375*38fd1498Szrj 376*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 377*38fd1498Szrj template<typename _InputIterator> 378*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 379*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 380*38fd1498Szrj _M_replace_dispatch(const_iterator __i1, const_iterator __i2, 381*38fd1498Szrj _InputIterator __k1, _InputIterator __k2, 382*38fd1498Szrj std::__false_type) 383*38fd1498Szrj { 384*38fd1498Szrj const basic_string __s(__k1, __k2); 385*38fd1498Szrj const size_type __n1 = __i2 - __i1; 386*38fd1498Szrj return _M_replace(__i1 - begin(), __n1, __s._M_data(), 387*38fd1498Szrj __s.size()); 388*38fd1498Szrj } 389*38fd1498Szrj 390*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 391*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 392*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 393*38fd1498Szrj _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 394*38fd1498Szrj _CharT __c) 395*38fd1498Szrj { 396*38fd1498Szrj _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 397*38fd1498Szrj 398*38fd1498Szrj const size_type __old_size = this->size(); 399*38fd1498Szrj const size_type __new_size = __old_size + __n2 - __n1; 400*38fd1498Szrj 401*38fd1498Szrj if (__new_size <= this->capacity()) 402*38fd1498Szrj { 403*38fd1498Szrj pointer __p = this->_M_data() + __pos1; 404*38fd1498Szrj 405*38fd1498Szrj const size_type __how_much = __old_size - __pos1 - __n1; 406*38fd1498Szrj if (__how_much && __n1 != __n2) 407*38fd1498Szrj this->_S_move(__p + __n2, __p + __n1, __how_much); 408*38fd1498Szrj } 409*38fd1498Szrj else 410*38fd1498Szrj this->_M_mutate(__pos1, __n1, 0, __n2); 411*38fd1498Szrj 412*38fd1498Szrj if (__n2) 413*38fd1498Szrj this->_S_assign(this->_M_data() + __pos1, __n2, __c); 414*38fd1498Szrj 415*38fd1498Szrj this->_M_set_length(__new_size); 416*38fd1498Szrj return *this; 417*38fd1498Szrj } 418*38fd1498Szrj 419*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 420*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 421*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 422*38fd1498Szrj _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 423*38fd1498Szrj const size_type __len2) 424*38fd1498Szrj { 425*38fd1498Szrj _M_check_length(__len1, __len2, "basic_string::_M_replace"); 426*38fd1498Szrj 427*38fd1498Szrj const size_type __old_size = this->size(); 428*38fd1498Szrj const size_type __new_size = __old_size + __len2 - __len1; 429*38fd1498Szrj 430*38fd1498Szrj if (__new_size <= this->capacity()) 431*38fd1498Szrj { 432*38fd1498Szrj pointer __p = this->_M_data() + __pos; 433*38fd1498Szrj 434*38fd1498Szrj const size_type __how_much = __old_size - __pos - __len1; 435*38fd1498Szrj if (_M_disjunct(__s)) 436*38fd1498Szrj { 437*38fd1498Szrj if (__how_much && __len1 != __len2) 438*38fd1498Szrj this->_S_move(__p + __len2, __p + __len1, __how_much); 439*38fd1498Szrj if (__len2) 440*38fd1498Szrj this->_S_copy(__p, __s, __len2); 441*38fd1498Szrj } 442*38fd1498Szrj else 443*38fd1498Szrj { 444*38fd1498Szrj // Work in-place. 445*38fd1498Szrj if (__len2 && __len2 <= __len1) 446*38fd1498Szrj this->_S_move(__p, __s, __len2); 447*38fd1498Szrj if (__how_much && __len1 != __len2) 448*38fd1498Szrj this->_S_move(__p + __len2, __p + __len1, __how_much); 449*38fd1498Szrj if (__len2 > __len1) 450*38fd1498Szrj { 451*38fd1498Szrj if (__s + __len2 <= __p + __len1) 452*38fd1498Szrj this->_S_move(__p, __s, __len2); 453*38fd1498Szrj else if (__s >= __p + __len1) 454*38fd1498Szrj this->_S_copy(__p, __s + __len2 - __len1, __len2); 455*38fd1498Szrj else 456*38fd1498Szrj { 457*38fd1498Szrj const size_type __nleft = (__p + __len1) - __s; 458*38fd1498Szrj this->_S_move(__p, __s, __nleft); 459*38fd1498Szrj this->_S_copy(__p + __nleft, __p + __len2, 460*38fd1498Szrj __len2 - __nleft); 461*38fd1498Szrj } 462*38fd1498Szrj } 463*38fd1498Szrj } 464*38fd1498Szrj } 465*38fd1498Szrj else 466*38fd1498Szrj this->_M_mutate(__pos, __len1, __s, __len2); 467*38fd1498Szrj 468*38fd1498Szrj this->_M_set_length(__new_size); 469*38fd1498Szrj return *this; 470*38fd1498Szrj } 471*38fd1498Szrj 472*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 473*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 474*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 475*38fd1498Szrj copy(_CharT* __s, size_type __n, size_type __pos) const 476*38fd1498Szrj { 477*38fd1498Szrj _M_check(__pos, "basic_string::copy"); 478*38fd1498Szrj __n = _M_limit(__pos, __n); 479*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 480*38fd1498Szrj if (__n) 481*38fd1498Szrj _S_copy(__s, _M_data() + __pos, __n); 482*38fd1498Szrj // 21.3.5.7 par 3: do not append null. (good.) 483*38fd1498Szrj return __n; 484*38fd1498Szrj } 485*38fd1498Szrj 486*38fd1498Szrj #else // !_GLIBCXX_USE_CXX11_ABI 487*38fd1498Szrj 488*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 489*38fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 490*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 491*38fd1498Szrj _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; 492*38fd1498Szrj 493*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 494*38fd1498Szrj const _CharT 495*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 496*38fd1498Szrj _Rep::_S_terminal = _CharT(); 497*38fd1498Szrj 498*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 499*38fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 500*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::npos; 501*38fd1498Szrj 502*38fd1498Szrj // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) 503*38fd1498Szrj // at static init time (before static ctors are run). 504*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 505*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 506*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ 507*38fd1498Szrj (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / 508*38fd1498Szrj sizeof(size_type)]; 509*38fd1498Szrj 510*38fd1498Szrj // NB: This is the special case for Input Iterators, used in 511*38fd1498Szrj // istreambuf_iterators, etc. 512*38fd1498Szrj // Input Iterators have a cost structure very different from 513*38fd1498Szrj // pointers, calling for a different coding style. 514*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 515*38fd1498Szrj template<typename _InIterator> 516*38fd1498Szrj _CharT* 517*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 518*38fd1498Szrj _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 519*38fd1498Szrj input_iterator_tag) 520*38fd1498Szrj { 521*38fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 522*38fd1498Szrj if (__beg == __end && __a == _Alloc()) 523*38fd1498Szrj return _S_empty_rep()._M_refdata(); 524*38fd1498Szrj #endif 525*38fd1498Szrj // Avoid reallocation for common case. 526*38fd1498Szrj _CharT __buf[128]; 527*38fd1498Szrj size_type __len = 0; 528*38fd1498Szrj while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) 529*38fd1498Szrj { 530*38fd1498Szrj __buf[__len++] = *__beg; 531*38fd1498Szrj ++__beg; 532*38fd1498Szrj } 533*38fd1498Szrj _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); 534*38fd1498Szrj _M_copy(__r->_M_refdata(), __buf, __len); 535*38fd1498Szrj __try 536*38fd1498Szrj { 537*38fd1498Szrj while (__beg != __end) 538*38fd1498Szrj { 539*38fd1498Szrj if (__len == __r->_M_capacity) 540*38fd1498Szrj { 541*38fd1498Szrj // Allocate more space. 542*38fd1498Szrj _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); 543*38fd1498Szrj _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); 544*38fd1498Szrj __r->_M_destroy(__a); 545*38fd1498Szrj __r = __another; 546*38fd1498Szrj } 547*38fd1498Szrj __r->_M_refdata()[__len++] = *__beg; 548*38fd1498Szrj ++__beg; 549*38fd1498Szrj } 550*38fd1498Szrj } 551*38fd1498Szrj __catch(...) 552*38fd1498Szrj { 553*38fd1498Szrj __r->_M_destroy(__a); 554*38fd1498Szrj __throw_exception_again; 555*38fd1498Szrj } 556*38fd1498Szrj __r->_M_set_length_and_sharable(__len); 557*38fd1498Szrj return __r->_M_refdata(); 558*38fd1498Szrj } 559*38fd1498Szrj 560*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 561*38fd1498Szrj template <typename _InIterator> 562*38fd1498Szrj _CharT* 563*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 564*38fd1498Szrj _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 565*38fd1498Szrj forward_iterator_tag) 566*38fd1498Szrj { 567*38fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 568*38fd1498Szrj if (__beg == __end && __a == _Alloc()) 569*38fd1498Szrj return _S_empty_rep()._M_refdata(); 570*38fd1498Szrj #endif 571*38fd1498Szrj // NB: Not required, but considered best practice. 572*38fd1498Szrj if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 573*38fd1498Szrj __throw_logic_error(__N("basic_string::_S_construct null not valid")); 574*38fd1498Szrj 575*38fd1498Szrj const size_type __dnew = static_cast<size_type>(std::distance(__beg, 576*38fd1498Szrj __end)); 577*38fd1498Szrj // Check for out_of_range and length_error exceptions. 578*38fd1498Szrj _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); 579*38fd1498Szrj __try 580*38fd1498Szrj { _S_copy_chars(__r->_M_refdata(), __beg, __end); } 581*38fd1498Szrj __catch(...) 582*38fd1498Szrj { 583*38fd1498Szrj __r->_M_destroy(__a); 584*38fd1498Szrj __throw_exception_again; 585*38fd1498Szrj } 586*38fd1498Szrj __r->_M_set_length_and_sharable(__dnew); 587*38fd1498Szrj return __r->_M_refdata(); 588*38fd1498Szrj } 589*38fd1498Szrj 590*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 591*38fd1498Szrj _CharT* 592*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 593*38fd1498Szrj _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 594*38fd1498Szrj { 595*38fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 596*38fd1498Szrj if (__n == 0 && __a == _Alloc()) 597*38fd1498Szrj return _S_empty_rep()._M_refdata(); 598*38fd1498Szrj #endif 599*38fd1498Szrj // Check for out_of_range and length_error exceptions. 600*38fd1498Szrj _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); 601*38fd1498Szrj if (__n) 602*38fd1498Szrj _M_assign(__r->_M_refdata(), __n, __c); 603*38fd1498Szrj 604*38fd1498Szrj __r->_M_set_length_and_sharable(__n); 605*38fd1498Szrj return __r->_M_refdata(); 606*38fd1498Szrj } 607*38fd1498Szrj 608*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 609*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 610*38fd1498Szrj basic_string(const basic_string& __str) 611*38fd1498Szrj : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), 612*38fd1498Szrj __str.get_allocator()), 613*38fd1498Szrj __str.get_allocator()) 614*38fd1498Szrj { } 615*38fd1498Szrj 616*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 617*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 618*38fd1498Szrj basic_string(const _Alloc& __a) 619*38fd1498Szrj : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) 620*38fd1498Szrj { } 621*38fd1498Szrj 622*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 623*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 624*38fd1498Szrj basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a) 625*38fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 626*38fd1498Szrj + __str._M_check(__pos, 627*38fd1498Szrj "basic_string::basic_string"), 628*38fd1498Szrj __str._M_data() + __str._M_limit(__pos, npos) 629*38fd1498Szrj + __pos, __a), __a) 630*38fd1498Szrj { } 631*38fd1498Szrj 632*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 633*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 634*38fd1498Szrj basic_string(const basic_string& __str, size_type __pos, size_type __n) 635*38fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 636*38fd1498Szrj + __str._M_check(__pos, 637*38fd1498Szrj "basic_string::basic_string"), 638*38fd1498Szrj __str._M_data() + __str._M_limit(__pos, __n) 639*38fd1498Szrj + __pos, _Alloc()), _Alloc()) 640*38fd1498Szrj { } 641*38fd1498Szrj 642*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 643*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 644*38fd1498Szrj basic_string(const basic_string& __str, size_type __pos, 645*38fd1498Szrj size_type __n, const _Alloc& __a) 646*38fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 647*38fd1498Szrj + __str._M_check(__pos, 648*38fd1498Szrj "basic_string::basic_string"), 649*38fd1498Szrj __str._M_data() + __str._M_limit(__pos, __n) 650*38fd1498Szrj + __pos, __a), __a) 651*38fd1498Szrj { } 652*38fd1498Szrj 653*38fd1498Szrj // TBD: DPG annotate 654*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 655*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 656*38fd1498Szrj basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) 657*38fd1498Szrj : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) 658*38fd1498Szrj { } 659*38fd1498Szrj 660*38fd1498Szrj // TBD: DPG annotate 661*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 662*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 663*38fd1498Szrj basic_string(const _CharT* __s, const _Alloc& __a) 664*38fd1498Szrj : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : 665*38fd1498Szrj __s + npos, __a), __a) 666*38fd1498Szrj { } 667*38fd1498Szrj 668*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 669*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 670*38fd1498Szrj basic_string(size_type __n, _CharT __c, const _Alloc& __a) 671*38fd1498Szrj : _M_dataplus(_S_construct(__n, __c, __a), __a) 672*38fd1498Szrj { } 673*38fd1498Szrj 674*38fd1498Szrj // TBD: DPG annotate 675*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 676*38fd1498Szrj template<typename _InputIterator> 677*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 678*38fd1498Szrj basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) 679*38fd1498Szrj : _M_dataplus(_S_construct(__beg, __end, __a), __a) 680*38fd1498Szrj { } 681*38fd1498Szrj 682*38fd1498Szrj #if __cplusplus >= 201103L 683*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 684*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 685*38fd1498Szrj basic_string(initializer_list<_CharT> __l, const _Alloc& __a) 686*38fd1498Szrj : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a) 687*38fd1498Szrj { } 688*38fd1498Szrj #endif 689*38fd1498Szrj 690*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 691*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 692*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 693*38fd1498Szrj assign(const basic_string& __str) 694*38fd1498Szrj { 695*38fd1498Szrj if (_M_rep() != __str._M_rep()) 696*38fd1498Szrj { 697*38fd1498Szrj // XXX MT 698*38fd1498Szrj const allocator_type __a = this->get_allocator(); 699*38fd1498Szrj _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); 700*38fd1498Szrj _M_rep()->_M_dispose(__a); 701*38fd1498Szrj _M_data(__tmp); 702*38fd1498Szrj } 703*38fd1498Szrj return *this; 704*38fd1498Szrj } 705*38fd1498Szrj 706*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 707*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 708*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 709*38fd1498Szrj assign(const _CharT* __s, size_type __n) 710*38fd1498Szrj { 711*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 712*38fd1498Szrj _M_check_length(this->size(), __n, "basic_string::assign"); 713*38fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 714*38fd1498Szrj return _M_replace_safe(size_type(0), this->size(), __s, __n); 715*38fd1498Szrj else 716*38fd1498Szrj { 717*38fd1498Szrj // Work in-place. 718*38fd1498Szrj const size_type __pos = __s - _M_data(); 719*38fd1498Szrj if (__pos >= __n) 720*38fd1498Szrj _M_copy(_M_data(), __s, __n); 721*38fd1498Szrj else if (__pos) 722*38fd1498Szrj _M_move(_M_data(), __s, __n); 723*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__n); 724*38fd1498Szrj return *this; 725*38fd1498Szrj } 726*38fd1498Szrj } 727*38fd1498Szrj 728*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 729*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 730*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 731*38fd1498Szrj append(size_type __n, _CharT __c) 732*38fd1498Szrj { 733*38fd1498Szrj if (__n) 734*38fd1498Szrj { 735*38fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::append"); 736*38fd1498Szrj const size_type __len = __n + this->size(); 737*38fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 738*38fd1498Szrj this->reserve(__len); 739*38fd1498Szrj _M_assign(_M_data() + this->size(), __n, __c); 740*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 741*38fd1498Szrj } 742*38fd1498Szrj return *this; 743*38fd1498Szrj } 744*38fd1498Szrj 745*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 746*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 747*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 748*38fd1498Szrj append(const _CharT* __s, size_type __n) 749*38fd1498Szrj { 750*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 751*38fd1498Szrj if (__n) 752*38fd1498Szrj { 753*38fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::append"); 754*38fd1498Szrj const size_type __len = __n + this->size(); 755*38fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 756*38fd1498Szrj { 757*38fd1498Szrj if (_M_disjunct(__s)) 758*38fd1498Szrj this->reserve(__len); 759*38fd1498Szrj else 760*38fd1498Szrj { 761*38fd1498Szrj const size_type __off = __s - _M_data(); 762*38fd1498Szrj this->reserve(__len); 763*38fd1498Szrj __s = _M_data() + __off; 764*38fd1498Szrj } 765*38fd1498Szrj } 766*38fd1498Szrj _M_copy(_M_data() + this->size(), __s, __n); 767*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 768*38fd1498Szrj } 769*38fd1498Szrj return *this; 770*38fd1498Szrj } 771*38fd1498Szrj 772*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 773*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 774*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 775*38fd1498Szrj append(const basic_string& __str) 776*38fd1498Szrj { 777*38fd1498Szrj const size_type __size = __str.size(); 778*38fd1498Szrj if (__size) 779*38fd1498Szrj { 780*38fd1498Szrj const size_type __len = __size + this->size(); 781*38fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 782*38fd1498Szrj this->reserve(__len); 783*38fd1498Szrj _M_copy(_M_data() + this->size(), __str._M_data(), __size); 784*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 785*38fd1498Szrj } 786*38fd1498Szrj return *this; 787*38fd1498Szrj } 788*38fd1498Szrj 789*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 790*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 791*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 792*38fd1498Szrj append(const basic_string& __str, size_type __pos, size_type __n) 793*38fd1498Szrj { 794*38fd1498Szrj __str._M_check(__pos, "basic_string::append"); 795*38fd1498Szrj __n = __str._M_limit(__pos, __n); 796*38fd1498Szrj if (__n) 797*38fd1498Szrj { 798*38fd1498Szrj const size_type __len = __n + this->size(); 799*38fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 800*38fd1498Szrj this->reserve(__len); 801*38fd1498Szrj _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); 802*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 803*38fd1498Szrj } 804*38fd1498Szrj return *this; 805*38fd1498Szrj } 806*38fd1498Szrj 807*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 808*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 809*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 810*38fd1498Szrj insert(size_type __pos, const _CharT* __s, size_type __n) 811*38fd1498Szrj { 812*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 813*38fd1498Szrj _M_check(__pos, "basic_string::insert"); 814*38fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::insert"); 815*38fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 816*38fd1498Szrj return _M_replace_safe(__pos, size_type(0), __s, __n); 817*38fd1498Szrj else 818*38fd1498Szrj { 819*38fd1498Szrj // Work in-place. 820*38fd1498Szrj const size_type __off = __s - _M_data(); 821*38fd1498Szrj _M_mutate(__pos, 0, __n); 822*38fd1498Szrj __s = _M_data() + __off; 823*38fd1498Szrj _CharT* __p = _M_data() + __pos; 824*38fd1498Szrj if (__s + __n <= __p) 825*38fd1498Szrj _M_copy(__p, __s, __n); 826*38fd1498Szrj else if (__s >= __p) 827*38fd1498Szrj _M_copy(__p, __s + __n, __n); 828*38fd1498Szrj else 829*38fd1498Szrj { 830*38fd1498Szrj const size_type __nleft = __p - __s; 831*38fd1498Szrj _M_copy(__p, __s, __nleft); 832*38fd1498Szrj _M_copy(__p + __nleft, __p + __n, __n - __nleft); 833*38fd1498Szrj } 834*38fd1498Szrj return *this; 835*38fd1498Szrj } 836*38fd1498Szrj } 837*38fd1498Szrj 838*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 839*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::iterator 840*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 841*38fd1498Szrj erase(iterator __first, iterator __last) 842*38fd1498Szrj { 843*38fd1498Szrj _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last 844*38fd1498Szrj && __last <= _M_iend()); 845*38fd1498Szrj 846*38fd1498Szrj // NB: This isn't just an optimization (bail out early when 847*38fd1498Szrj // there is nothing to do, really), it's also a correctness 848*38fd1498Szrj // issue vs MT, see libstdc++/40518. 849*38fd1498Szrj const size_type __size = __last - __first; 850*38fd1498Szrj if (__size) 851*38fd1498Szrj { 852*38fd1498Szrj const size_type __pos = __first - _M_ibegin(); 853*38fd1498Szrj _M_mutate(__pos, __size, size_type(0)); 854*38fd1498Szrj _M_rep()->_M_set_leaked(); 855*38fd1498Szrj return iterator(_M_data() + __pos); 856*38fd1498Szrj } 857*38fd1498Szrj else 858*38fd1498Szrj return __first; 859*38fd1498Szrj } 860*38fd1498Szrj 861*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 862*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 863*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 864*38fd1498Szrj replace(size_type __pos, size_type __n1, const _CharT* __s, 865*38fd1498Szrj size_type __n2) 866*38fd1498Szrj { 867*38fd1498Szrj __glibcxx_requires_string_len(__s, __n2); 868*38fd1498Szrj _M_check(__pos, "basic_string::replace"); 869*38fd1498Szrj __n1 = _M_limit(__pos, __n1); 870*38fd1498Szrj _M_check_length(__n1, __n2, "basic_string::replace"); 871*38fd1498Szrj bool __left; 872*38fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 873*38fd1498Szrj return _M_replace_safe(__pos, __n1, __s, __n2); 874*38fd1498Szrj else if ((__left = __s + __n2 <= _M_data() + __pos) 875*38fd1498Szrj || _M_data() + __pos + __n1 <= __s) 876*38fd1498Szrj { 877*38fd1498Szrj // Work in-place: non-overlapping case. 878*38fd1498Szrj size_type __off = __s - _M_data(); 879*38fd1498Szrj __left ? __off : (__off += __n2 - __n1); 880*38fd1498Szrj _M_mutate(__pos, __n1, __n2); 881*38fd1498Szrj _M_copy(_M_data() + __pos, _M_data() + __off, __n2); 882*38fd1498Szrj return *this; 883*38fd1498Szrj } 884*38fd1498Szrj else 885*38fd1498Szrj { 886*38fd1498Szrj // Todo: overlapping case. 887*38fd1498Szrj const basic_string __tmp(__s, __n2); 888*38fd1498Szrj return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); 889*38fd1498Szrj } 890*38fd1498Szrj } 891*38fd1498Szrj 892*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 893*38fd1498Szrj void 894*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 895*38fd1498Szrj _M_destroy(const _Alloc& __a) throw () 896*38fd1498Szrj { 897*38fd1498Szrj const size_type __size = sizeof(_Rep_base) + 898*38fd1498Szrj (this->_M_capacity + 1) * sizeof(_CharT); 899*38fd1498Szrj _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); 900*38fd1498Szrj } 901*38fd1498Szrj 902*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 903*38fd1498Szrj void 904*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 905*38fd1498Szrj _M_leak_hard() 906*38fd1498Szrj { 907*38fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 908*38fd1498Szrj if (_M_rep() == &_S_empty_rep()) 909*38fd1498Szrj return; 910*38fd1498Szrj #endif 911*38fd1498Szrj if (_M_rep()->_M_is_shared()) 912*38fd1498Szrj _M_mutate(0, 0, 0); 913*38fd1498Szrj _M_rep()->_M_set_leaked(); 914*38fd1498Szrj } 915*38fd1498Szrj 916*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 917*38fd1498Szrj void 918*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 919*38fd1498Szrj _M_mutate(size_type __pos, size_type __len1, size_type __len2) 920*38fd1498Szrj { 921*38fd1498Szrj const size_type __old_size = this->size(); 922*38fd1498Szrj const size_type __new_size = __old_size + __len2 - __len1; 923*38fd1498Szrj const size_type __how_much = __old_size - __pos - __len1; 924*38fd1498Szrj 925*38fd1498Szrj if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) 926*38fd1498Szrj { 927*38fd1498Szrj // Must reallocate. 928*38fd1498Szrj const allocator_type __a = get_allocator(); 929*38fd1498Szrj _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); 930*38fd1498Szrj 931*38fd1498Szrj if (__pos) 932*38fd1498Szrj _M_copy(__r->_M_refdata(), _M_data(), __pos); 933*38fd1498Szrj if (__how_much) 934*38fd1498Szrj _M_copy(__r->_M_refdata() + __pos + __len2, 935*38fd1498Szrj _M_data() + __pos + __len1, __how_much); 936*38fd1498Szrj 937*38fd1498Szrj _M_rep()->_M_dispose(__a); 938*38fd1498Szrj _M_data(__r->_M_refdata()); 939*38fd1498Szrj } 940*38fd1498Szrj else if (__how_much && __len1 != __len2) 941*38fd1498Szrj { 942*38fd1498Szrj // Work in-place. 943*38fd1498Szrj _M_move(_M_data() + __pos + __len2, 944*38fd1498Szrj _M_data() + __pos + __len1, __how_much); 945*38fd1498Szrj } 946*38fd1498Szrj _M_rep()->_M_set_length_and_sharable(__new_size); 947*38fd1498Szrj } 948*38fd1498Szrj 949*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 950*38fd1498Szrj void 951*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 952*38fd1498Szrj reserve(size_type __res) 953*38fd1498Szrj { 954*38fd1498Szrj if (__res != this->capacity() || _M_rep()->_M_is_shared()) 955*38fd1498Szrj { 956*38fd1498Szrj // Make sure we don't shrink below the current size 957*38fd1498Szrj if (__res < this->size()) 958*38fd1498Szrj __res = this->size(); 959*38fd1498Szrj const allocator_type __a = get_allocator(); 960*38fd1498Szrj _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); 961*38fd1498Szrj _M_rep()->_M_dispose(__a); 962*38fd1498Szrj _M_data(__tmp); 963*38fd1498Szrj } 964*38fd1498Szrj } 965*38fd1498Szrj 966*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 967*38fd1498Szrj void 968*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 969*38fd1498Szrj swap(basic_string& __s) 970*38fd1498Szrj { 971*38fd1498Szrj if (_M_rep()->_M_is_leaked()) 972*38fd1498Szrj _M_rep()->_M_set_sharable(); 973*38fd1498Szrj if (__s._M_rep()->_M_is_leaked()) 974*38fd1498Szrj __s._M_rep()->_M_set_sharable(); 975*38fd1498Szrj if (this->get_allocator() == __s.get_allocator()) 976*38fd1498Szrj { 977*38fd1498Szrj _CharT* __tmp = _M_data(); 978*38fd1498Szrj _M_data(__s._M_data()); 979*38fd1498Szrj __s._M_data(__tmp); 980*38fd1498Szrj } 981*38fd1498Szrj // The code below can usually be optimized away. 982*38fd1498Szrj else 983*38fd1498Szrj { 984*38fd1498Szrj const basic_string __tmp1(_M_ibegin(), _M_iend(), 985*38fd1498Szrj __s.get_allocator()); 986*38fd1498Szrj const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 987*38fd1498Szrj this->get_allocator()); 988*38fd1498Szrj *this = __tmp2; 989*38fd1498Szrj __s = __tmp1; 990*38fd1498Szrj } 991*38fd1498Szrj } 992*38fd1498Szrj 993*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 994*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::_Rep* 995*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 996*38fd1498Szrj _S_create(size_type __capacity, size_type __old_capacity, 997*38fd1498Szrj const _Alloc& __alloc) 998*38fd1498Szrj { 999*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1000*38fd1498Szrj // 83. String::npos vs. string::max_size() 1001*38fd1498Szrj if (__capacity > _S_max_size) 1002*38fd1498Szrj __throw_length_error(__N("basic_string::_S_create")); 1003*38fd1498Szrj 1004*38fd1498Szrj // The standard places no restriction on allocating more memory 1005*38fd1498Szrj // than is strictly needed within this layer at the moment or as 1006*38fd1498Szrj // requested by an explicit application call to reserve(). 1007*38fd1498Szrj 1008*38fd1498Szrj // Many malloc implementations perform quite poorly when an 1009*38fd1498Szrj // application attempts to allocate memory in a stepwise fashion 1010*38fd1498Szrj // growing each allocation size by only 1 char. Additionally, 1011*38fd1498Szrj // it makes little sense to allocate less linear memory than the 1012*38fd1498Szrj // natural blocking size of the malloc implementation. 1013*38fd1498Szrj // Unfortunately, we would need a somewhat low-level calculation 1014*38fd1498Szrj // with tuned parameters to get this perfect for any particular 1015*38fd1498Szrj // malloc implementation. Fortunately, generalizations about 1016*38fd1498Szrj // common features seen among implementations seems to suffice. 1017*38fd1498Szrj 1018*38fd1498Szrj // __pagesize need not match the actual VM page size for good 1019*38fd1498Szrj // results in practice, thus we pick a common value on the low 1020*38fd1498Szrj // side. __malloc_header_size is an estimate of the amount of 1021*38fd1498Szrj // overhead per memory allocation (in practice seen N * sizeof 1022*38fd1498Szrj // (void*) where N is 0, 2 or 4). According to folklore, 1023*38fd1498Szrj // picking this value on the high side is better than 1024*38fd1498Szrj // low-balling it (especially when this algorithm is used with 1025*38fd1498Szrj // malloc implementations that allocate memory blocks rounded up 1026*38fd1498Szrj // to a size which is a power of 2). 1027*38fd1498Szrj const size_type __pagesize = 4096; 1028*38fd1498Szrj const size_type __malloc_header_size = 4 * sizeof(void*); 1029*38fd1498Szrj 1030*38fd1498Szrj // The below implements an exponential growth policy, necessary to 1031*38fd1498Szrj // meet amortized linear time requirements of the library: see 1032*38fd1498Szrj // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 1033*38fd1498Szrj // It's active for allocations requiring an amount of memory above 1034*38fd1498Szrj // system pagesize. This is consistent with the requirements of the 1035*38fd1498Szrj // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html 1036*38fd1498Szrj if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 1037*38fd1498Szrj __capacity = 2 * __old_capacity; 1038*38fd1498Szrj 1039*38fd1498Szrj // NB: Need an array of char_type[__capacity], plus a terminating 1040*38fd1498Szrj // null char_type() element, plus enough for the _Rep data structure. 1041*38fd1498Szrj // Whew. Seemingly so needy, yet so elemental. 1042*38fd1498Szrj size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 1043*38fd1498Szrj 1044*38fd1498Szrj const size_type __adj_size = __size + __malloc_header_size; 1045*38fd1498Szrj if (__adj_size > __pagesize && __capacity > __old_capacity) 1046*38fd1498Szrj { 1047*38fd1498Szrj const size_type __extra = __pagesize - __adj_size % __pagesize; 1048*38fd1498Szrj __capacity += __extra / sizeof(_CharT); 1049*38fd1498Szrj // Never allocate a string bigger than _S_max_size. 1050*38fd1498Szrj if (__capacity > _S_max_size) 1051*38fd1498Szrj __capacity = _S_max_size; 1052*38fd1498Szrj __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 1053*38fd1498Szrj } 1054*38fd1498Szrj 1055*38fd1498Szrj // NB: Might throw, but no worries about a leak, mate: _Rep() 1056*38fd1498Szrj // does not throw. 1057*38fd1498Szrj void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); 1058*38fd1498Szrj _Rep *__p = new (__place) _Rep; 1059*38fd1498Szrj __p->_M_capacity = __capacity; 1060*38fd1498Szrj // ABI compatibility - 3.4.x set in _S_create both 1061*38fd1498Szrj // _M_refcount and _M_length. All callers of _S_create 1062*38fd1498Szrj // in basic_string.tcc then set just _M_length. 1063*38fd1498Szrj // In 4.0.x and later both _M_refcount and _M_length 1064*38fd1498Szrj // are initialized in the callers, unfortunately we can 1065*38fd1498Szrj // have 3.4.x compiled code with _S_create callers inlined 1066*38fd1498Szrj // calling 4.0.x+ _S_create. 1067*38fd1498Szrj __p->_M_set_sharable(); 1068*38fd1498Szrj return __p; 1069*38fd1498Szrj } 1070*38fd1498Szrj 1071*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1072*38fd1498Szrj _CharT* 1073*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 1074*38fd1498Szrj _M_clone(const _Alloc& __alloc, size_type __res) 1075*38fd1498Szrj { 1076*38fd1498Szrj // Requested capacity of the clone. 1077*38fd1498Szrj const size_type __requested_cap = this->_M_length + __res; 1078*38fd1498Szrj _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, 1079*38fd1498Szrj __alloc); 1080*38fd1498Szrj if (this->_M_length) 1081*38fd1498Szrj _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); 1082*38fd1498Szrj 1083*38fd1498Szrj __r->_M_set_length_and_sharable(this->_M_length); 1084*38fd1498Szrj return __r->_M_refdata(); 1085*38fd1498Szrj } 1086*38fd1498Szrj 1087*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1088*38fd1498Szrj void 1089*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1090*38fd1498Szrj resize(size_type __n, _CharT __c) 1091*38fd1498Szrj { 1092*38fd1498Szrj const size_type __size = this->size(); 1093*38fd1498Szrj _M_check_length(__size, __n, "basic_string::resize"); 1094*38fd1498Szrj if (__size < __n) 1095*38fd1498Szrj this->append(__n - __size, __c); 1096*38fd1498Szrj else if (__n < __size) 1097*38fd1498Szrj this->erase(__n); 1098*38fd1498Szrj // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) 1099*38fd1498Szrj } 1100*38fd1498Szrj 1101*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1102*38fd1498Szrj template<typename _InputIterator> 1103*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 1104*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1105*38fd1498Szrj _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 1106*38fd1498Szrj _InputIterator __k2, __false_type) 1107*38fd1498Szrj { 1108*38fd1498Szrj const basic_string __s(__k1, __k2); 1109*38fd1498Szrj const size_type __n1 = __i2 - __i1; 1110*38fd1498Szrj _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); 1111*38fd1498Szrj return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), 1112*38fd1498Szrj __s.size()); 1113*38fd1498Szrj } 1114*38fd1498Szrj 1115*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1116*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 1117*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1118*38fd1498Szrj _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 1119*38fd1498Szrj _CharT __c) 1120*38fd1498Szrj { 1121*38fd1498Szrj _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 1122*38fd1498Szrj _M_mutate(__pos1, __n1, __n2); 1123*38fd1498Szrj if (__n2) 1124*38fd1498Szrj _M_assign(_M_data() + __pos1, __n2, __c); 1125*38fd1498Szrj return *this; 1126*38fd1498Szrj } 1127*38fd1498Szrj 1128*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1129*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 1130*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1131*38fd1498Szrj _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, 1132*38fd1498Szrj size_type __n2) 1133*38fd1498Szrj { 1134*38fd1498Szrj _M_mutate(__pos1, __n1, __n2); 1135*38fd1498Szrj if (__n2) 1136*38fd1498Szrj _M_copy(_M_data() + __pos1, __s, __n2); 1137*38fd1498Szrj return *this; 1138*38fd1498Szrj } 1139*38fd1498Szrj 1140*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1141*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1142*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1143*38fd1498Szrj copy(_CharT* __s, size_type __n, size_type __pos) const 1144*38fd1498Szrj { 1145*38fd1498Szrj _M_check(__pos, "basic_string::copy"); 1146*38fd1498Szrj __n = _M_limit(__pos, __n); 1147*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1148*38fd1498Szrj if (__n) 1149*38fd1498Szrj _M_copy(__s, _M_data() + __pos, __n); 1150*38fd1498Szrj // 21.3.5.7 par 3: do not append null. (good.) 1151*38fd1498Szrj return __n; 1152*38fd1498Szrj } 1153*38fd1498Szrj #endif // !_GLIBCXX_USE_CXX11_ABI 1154*38fd1498Szrj 1155*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1156*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc> 1157*38fd1498Szrj operator+(const _CharT* __lhs, 1158*38fd1498Szrj const basic_string<_CharT, _Traits, _Alloc>& __rhs) 1159*38fd1498Szrj { 1160*38fd1498Szrj __glibcxx_requires_string(__lhs); 1161*38fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1162*38fd1498Szrj typedef typename __string_type::size_type __size_type; 1163*38fd1498Szrj const __size_type __len = _Traits::length(__lhs); 1164*38fd1498Szrj __string_type __str; 1165*38fd1498Szrj __str.reserve(__len + __rhs.size()); 1166*38fd1498Szrj __str.append(__lhs, __len); 1167*38fd1498Szrj __str.append(__rhs); 1168*38fd1498Szrj return __str; 1169*38fd1498Szrj } 1170*38fd1498Szrj 1171*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1172*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc> 1173*38fd1498Szrj operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) 1174*38fd1498Szrj { 1175*38fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1176*38fd1498Szrj typedef typename __string_type::size_type __size_type; 1177*38fd1498Szrj __string_type __str; 1178*38fd1498Szrj const __size_type __len = __rhs.size(); 1179*38fd1498Szrj __str.reserve(__len + 1); 1180*38fd1498Szrj __str.append(__size_type(1), __lhs); 1181*38fd1498Szrj __str.append(__rhs); 1182*38fd1498Szrj return __str; 1183*38fd1498Szrj } 1184*38fd1498Szrj 1185*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1186*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1187*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1188*38fd1498Szrj find(const _CharT* __s, size_type __pos, size_type __n) const 1189*38fd1498Szrj _GLIBCXX_NOEXCEPT 1190*38fd1498Szrj { 1191*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1192*38fd1498Szrj const size_type __size = this->size(); 1193*38fd1498Szrj 1194*38fd1498Szrj if (__n == 0) 1195*38fd1498Szrj return __pos <= __size ? __pos : npos; 1196*38fd1498Szrj if (__pos >= __size) 1197*38fd1498Szrj return npos; 1198*38fd1498Szrj 1199*38fd1498Szrj const _CharT __elem0 = __s[0]; 1200*38fd1498Szrj const _CharT* const __data = data(); 1201*38fd1498Szrj const _CharT* __first = __data + __pos; 1202*38fd1498Szrj const _CharT* const __last = __data + __size; 1203*38fd1498Szrj size_type __len = __size - __pos; 1204*38fd1498Szrj 1205*38fd1498Szrj while (__len >= __n) 1206*38fd1498Szrj { 1207*38fd1498Szrj // Find the first occurrence of __elem0: 1208*38fd1498Szrj __first = traits_type::find(__first, __len - __n + 1, __elem0); 1209*38fd1498Szrj if (!__first) 1210*38fd1498Szrj return npos; 1211*38fd1498Szrj // Compare the full strings from the first occurrence of __elem0. 1212*38fd1498Szrj // We already know that __first[0] == __s[0] but compare them again 1213*38fd1498Szrj // anyway because __s is probably aligned, which helps memcmp. 1214*38fd1498Szrj if (traits_type::compare(__first, __s, __n) == 0) 1215*38fd1498Szrj return __first - __data; 1216*38fd1498Szrj __len = __last - ++__first; 1217*38fd1498Szrj } 1218*38fd1498Szrj return npos; 1219*38fd1498Szrj } 1220*38fd1498Szrj 1221*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1222*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1223*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1224*38fd1498Szrj find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 1225*38fd1498Szrj { 1226*38fd1498Szrj size_type __ret = npos; 1227*38fd1498Szrj const size_type __size = this->size(); 1228*38fd1498Szrj if (__pos < __size) 1229*38fd1498Szrj { 1230*38fd1498Szrj const _CharT* __data = _M_data(); 1231*38fd1498Szrj const size_type __n = __size - __pos; 1232*38fd1498Szrj const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 1233*38fd1498Szrj if (__p) 1234*38fd1498Szrj __ret = __p - __data; 1235*38fd1498Szrj } 1236*38fd1498Szrj return __ret; 1237*38fd1498Szrj } 1238*38fd1498Szrj 1239*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1240*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1241*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1242*38fd1498Szrj rfind(const _CharT* __s, size_type __pos, size_type __n) const 1243*38fd1498Szrj _GLIBCXX_NOEXCEPT 1244*38fd1498Szrj { 1245*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1246*38fd1498Szrj const size_type __size = this->size(); 1247*38fd1498Szrj if (__n <= __size) 1248*38fd1498Szrj { 1249*38fd1498Szrj __pos = std::min(size_type(__size - __n), __pos); 1250*38fd1498Szrj const _CharT* __data = _M_data(); 1251*38fd1498Szrj do 1252*38fd1498Szrj { 1253*38fd1498Szrj if (traits_type::compare(__data + __pos, __s, __n) == 0) 1254*38fd1498Szrj return __pos; 1255*38fd1498Szrj } 1256*38fd1498Szrj while (__pos-- > 0); 1257*38fd1498Szrj } 1258*38fd1498Szrj return npos; 1259*38fd1498Szrj } 1260*38fd1498Szrj 1261*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1262*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1263*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1264*38fd1498Szrj rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 1265*38fd1498Szrj { 1266*38fd1498Szrj size_type __size = this->size(); 1267*38fd1498Szrj if (__size) 1268*38fd1498Szrj { 1269*38fd1498Szrj if (--__size > __pos) 1270*38fd1498Szrj __size = __pos; 1271*38fd1498Szrj for (++__size; __size-- > 0; ) 1272*38fd1498Szrj if (traits_type::eq(_M_data()[__size], __c)) 1273*38fd1498Szrj return __size; 1274*38fd1498Szrj } 1275*38fd1498Szrj return npos; 1276*38fd1498Szrj } 1277*38fd1498Szrj 1278*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1279*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1280*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1281*38fd1498Szrj find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 1282*38fd1498Szrj _GLIBCXX_NOEXCEPT 1283*38fd1498Szrj { 1284*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1285*38fd1498Szrj for (; __n && __pos < this->size(); ++__pos) 1286*38fd1498Szrj { 1287*38fd1498Szrj const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 1288*38fd1498Szrj if (__p) 1289*38fd1498Szrj return __pos; 1290*38fd1498Szrj } 1291*38fd1498Szrj return npos; 1292*38fd1498Szrj } 1293*38fd1498Szrj 1294*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1295*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1296*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1297*38fd1498Szrj find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 1298*38fd1498Szrj _GLIBCXX_NOEXCEPT 1299*38fd1498Szrj { 1300*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1301*38fd1498Szrj size_type __size = this->size(); 1302*38fd1498Szrj if (__size && __n) 1303*38fd1498Szrj { 1304*38fd1498Szrj if (--__size > __pos) 1305*38fd1498Szrj __size = __pos; 1306*38fd1498Szrj do 1307*38fd1498Szrj { 1308*38fd1498Szrj if (traits_type::find(__s, __n, _M_data()[__size])) 1309*38fd1498Szrj return __size; 1310*38fd1498Szrj } 1311*38fd1498Szrj while (__size-- != 0); 1312*38fd1498Szrj } 1313*38fd1498Szrj return npos; 1314*38fd1498Szrj } 1315*38fd1498Szrj 1316*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1317*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1318*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1319*38fd1498Szrj find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 1320*38fd1498Szrj _GLIBCXX_NOEXCEPT 1321*38fd1498Szrj { 1322*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1323*38fd1498Szrj for (; __pos < this->size(); ++__pos) 1324*38fd1498Szrj if (!traits_type::find(__s, __n, _M_data()[__pos])) 1325*38fd1498Szrj return __pos; 1326*38fd1498Szrj return npos; 1327*38fd1498Szrj } 1328*38fd1498Szrj 1329*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1330*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1331*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1332*38fd1498Szrj find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 1333*38fd1498Szrj { 1334*38fd1498Szrj for (; __pos < this->size(); ++__pos) 1335*38fd1498Szrj if (!traits_type::eq(_M_data()[__pos], __c)) 1336*38fd1498Szrj return __pos; 1337*38fd1498Szrj return npos; 1338*38fd1498Szrj } 1339*38fd1498Szrj 1340*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1341*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1342*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1343*38fd1498Szrj find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 1344*38fd1498Szrj _GLIBCXX_NOEXCEPT 1345*38fd1498Szrj { 1346*38fd1498Szrj __glibcxx_requires_string_len(__s, __n); 1347*38fd1498Szrj size_type __size = this->size(); 1348*38fd1498Szrj if (__size) 1349*38fd1498Szrj { 1350*38fd1498Szrj if (--__size > __pos) 1351*38fd1498Szrj __size = __pos; 1352*38fd1498Szrj do 1353*38fd1498Szrj { 1354*38fd1498Szrj if (!traits_type::find(__s, __n, _M_data()[__size])) 1355*38fd1498Szrj return __size; 1356*38fd1498Szrj } 1357*38fd1498Szrj while (__size--); 1358*38fd1498Szrj } 1359*38fd1498Szrj return npos; 1360*38fd1498Szrj } 1361*38fd1498Szrj 1362*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1363*38fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 1364*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1365*38fd1498Szrj find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 1366*38fd1498Szrj { 1367*38fd1498Szrj size_type __size = this->size(); 1368*38fd1498Szrj if (__size) 1369*38fd1498Szrj { 1370*38fd1498Szrj if (--__size > __pos) 1371*38fd1498Szrj __size = __pos; 1372*38fd1498Szrj do 1373*38fd1498Szrj { 1374*38fd1498Szrj if (!traits_type::eq(_M_data()[__size], __c)) 1375*38fd1498Szrj return __size; 1376*38fd1498Szrj } 1377*38fd1498Szrj while (__size--); 1378*38fd1498Szrj } 1379*38fd1498Szrj return npos; 1380*38fd1498Szrj } 1381*38fd1498Szrj 1382*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1383*38fd1498Szrj int 1384*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1385*38fd1498Szrj compare(size_type __pos, size_type __n, const basic_string& __str) const 1386*38fd1498Szrj { 1387*38fd1498Szrj _M_check(__pos, "basic_string::compare"); 1388*38fd1498Szrj __n = _M_limit(__pos, __n); 1389*38fd1498Szrj const size_type __osize = __str.size(); 1390*38fd1498Szrj const size_type __len = std::min(__n, __osize); 1391*38fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 1392*38fd1498Szrj if (!__r) 1393*38fd1498Szrj __r = _S_compare(__n, __osize); 1394*38fd1498Szrj return __r; 1395*38fd1498Szrj } 1396*38fd1498Szrj 1397*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1398*38fd1498Szrj int 1399*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1400*38fd1498Szrj compare(size_type __pos1, size_type __n1, const basic_string& __str, 1401*38fd1498Szrj size_type __pos2, size_type __n2) const 1402*38fd1498Szrj { 1403*38fd1498Szrj _M_check(__pos1, "basic_string::compare"); 1404*38fd1498Szrj __str._M_check(__pos2, "basic_string::compare"); 1405*38fd1498Szrj __n1 = _M_limit(__pos1, __n1); 1406*38fd1498Szrj __n2 = __str._M_limit(__pos2, __n2); 1407*38fd1498Szrj const size_type __len = std::min(__n1, __n2); 1408*38fd1498Szrj int __r = traits_type::compare(_M_data() + __pos1, 1409*38fd1498Szrj __str.data() + __pos2, __len); 1410*38fd1498Szrj if (!__r) 1411*38fd1498Szrj __r = _S_compare(__n1, __n2); 1412*38fd1498Szrj return __r; 1413*38fd1498Szrj } 1414*38fd1498Szrj 1415*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1416*38fd1498Szrj int 1417*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 1418*38fd1498Szrj compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT 1419*38fd1498Szrj { 1420*38fd1498Szrj __glibcxx_requires_string(__s); 1421*38fd1498Szrj const size_type __size = this->size(); 1422*38fd1498Szrj const size_type __osize = traits_type::length(__s); 1423*38fd1498Szrj const size_type __len = std::min(__size, __osize); 1424*38fd1498Szrj int __r = traits_type::compare(_M_data(), __s, __len); 1425*38fd1498Szrj if (!__r) 1426*38fd1498Szrj __r = _S_compare(__size, __osize); 1427*38fd1498Szrj return __r; 1428*38fd1498Szrj } 1429*38fd1498Szrj 1430*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1431*38fd1498Szrj int 1432*38fd1498Szrj basic_string <_CharT, _Traits, _Alloc>:: 1433*38fd1498Szrj compare(size_type __pos, size_type __n1, const _CharT* __s) const 1434*38fd1498Szrj { 1435*38fd1498Szrj __glibcxx_requires_string(__s); 1436*38fd1498Szrj _M_check(__pos, "basic_string::compare"); 1437*38fd1498Szrj __n1 = _M_limit(__pos, __n1); 1438*38fd1498Szrj const size_type __osize = traits_type::length(__s); 1439*38fd1498Szrj const size_type __len = std::min(__n1, __osize); 1440*38fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __s, __len); 1441*38fd1498Szrj if (!__r) 1442*38fd1498Szrj __r = _S_compare(__n1, __osize); 1443*38fd1498Szrj return __r; 1444*38fd1498Szrj } 1445*38fd1498Szrj 1446*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1447*38fd1498Szrj int 1448*38fd1498Szrj basic_string <_CharT, _Traits, _Alloc>:: 1449*38fd1498Szrj compare(size_type __pos, size_type __n1, const _CharT* __s, 1450*38fd1498Szrj size_type __n2) const 1451*38fd1498Szrj { 1452*38fd1498Szrj __glibcxx_requires_string_len(__s, __n2); 1453*38fd1498Szrj _M_check(__pos, "basic_string::compare"); 1454*38fd1498Szrj __n1 = _M_limit(__pos, __n1); 1455*38fd1498Szrj const size_type __len = std::min(__n1, __n2); 1456*38fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __s, __len); 1457*38fd1498Szrj if (!__r) 1458*38fd1498Szrj __r = _S_compare(__n1, __n2); 1459*38fd1498Szrj return __r; 1460*38fd1498Szrj } 1461*38fd1498Szrj 1462*38fd1498Szrj // 21.3.7.9 basic_string::getline and operators 1463*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1464*38fd1498Szrj basic_istream<_CharT, _Traits>& 1465*38fd1498Szrj operator>>(basic_istream<_CharT, _Traits>& __in, 1466*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& __str) 1467*38fd1498Szrj { 1468*38fd1498Szrj typedef basic_istream<_CharT, _Traits> __istream_type; 1469*38fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1470*38fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 1471*38fd1498Szrj typedef typename __istream_type::int_type __int_type; 1472*38fd1498Szrj typedef typename __string_type::size_type __size_type; 1473*38fd1498Szrj typedef ctype<_CharT> __ctype_type; 1474*38fd1498Szrj typedef typename __ctype_type::ctype_base __ctype_base; 1475*38fd1498Szrj 1476*38fd1498Szrj __size_type __extracted = 0; 1477*38fd1498Szrj typename __ios_base::iostate __err = __ios_base::goodbit; 1478*38fd1498Szrj typename __istream_type::sentry __cerb(__in, false); 1479*38fd1498Szrj if (__cerb) 1480*38fd1498Szrj { 1481*38fd1498Szrj __try 1482*38fd1498Szrj { 1483*38fd1498Szrj // Avoid reallocation for common case. 1484*38fd1498Szrj __str.erase(); 1485*38fd1498Szrj _CharT __buf[128]; 1486*38fd1498Szrj __size_type __len = 0; 1487*38fd1498Szrj const streamsize __w = __in.width(); 1488*38fd1498Szrj const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 1489*38fd1498Szrj : __str.max_size(); 1490*38fd1498Szrj const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 1491*38fd1498Szrj const __int_type __eof = _Traits::eof(); 1492*38fd1498Szrj __int_type __c = __in.rdbuf()->sgetc(); 1493*38fd1498Szrj 1494*38fd1498Szrj while (__extracted < __n 1495*38fd1498Szrj && !_Traits::eq_int_type(__c, __eof) 1496*38fd1498Szrj && !__ct.is(__ctype_base::space, 1497*38fd1498Szrj _Traits::to_char_type(__c))) 1498*38fd1498Szrj { 1499*38fd1498Szrj if (__len == sizeof(__buf) / sizeof(_CharT)) 1500*38fd1498Szrj { 1501*38fd1498Szrj __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 1502*38fd1498Szrj __len = 0; 1503*38fd1498Szrj } 1504*38fd1498Szrj __buf[__len++] = _Traits::to_char_type(__c); 1505*38fd1498Szrj ++__extracted; 1506*38fd1498Szrj __c = __in.rdbuf()->snextc(); 1507*38fd1498Szrj } 1508*38fd1498Szrj __str.append(__buf, __len); 1509*38fd1498Szrj 1510*38fd1498Szrj if (_Traits::eq_int_type(__c, __eof)) 1511*38fd1498Szrj __err |= __ios_base::eofbit; 1512*38fd1498Szrj __in.width(0); 1513*38fd1498Szrj } 1514*38fd1498Szrj __catch(__cxxabiv1::__forced_unwind&) 1515*38fd1498Szrj { 1516*38fd1498Szrj __in._M_setstate(__ios_base::badbit); 1517*38fd1498Szrj __throw_exception_again; 1518*38fd1498Szrj } 1519*38fd1498Szrj __catch(...) 1520*38fd1498Szrj { 1521*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1522*38fd1498Szrj // 91. Description of operator>> and getline() for string<> 1523*38fd1498Szrj // might cause endless loop 1524*38fd1498Szrj __in._M_setstate(__ios_base::badbit); 1525*38fd1498Szrj } 1526*38fd1498Szrj } 1527*38fd1498Szrj // 211. operator>>(istream&, string&) doesn't set failbit 1528*38fd1498Szrj if (!__extracted) 1529*38fd1498Szrj __err |= __ios_base::failbit; 1530*38fd1498Szrj if (__err) 1531*38fd1498Szrj __in.setstate(__err); 1532*38fd1498Szrj return __in; 1533*38fd1498Szrj } 1534*38fd1498Szrj 1535*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 1536*38fd1498Szrj basic_istream<_CharT, _Traits>& 1537*38fd1498Szrj getline(basic_istream<_CharT, _Traits>& __in, 1538*38fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 1539*38fd1498Szrj { 1540*38fd1498Szrj typedef basic_istream<_CharT, _Traits> __istream_type; 1541*38fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1542*38fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 1543*38fd1498Szrj typedef typename __istream_type::int_type __int_type; 1544*38fd1498Szrj typedef typename __string_type::size_type __size_type; 1545*38fd1498Szrj 1546*38fd1498Szrj __size_type __extracted = 0; 1547*38fd1498Szrj const __size_type __n = __str.max_size(); 1548*38fd1498Szrj typename __ios_base::iostate __err = __ios_base::goodbit; 1549*38fd1498Szrj typename __istream_type::sentry __cerb(__in, true); 1550*38fd1498Szrj if (__cerb) 1551*38fd1498Szrj { 1552*38fd1498Szrj __try 1553*38fd1498Szrj { 1554*38fd1498Szrj __str.erase(); 1555*38fd1498Szrj const __int_type __idelim = _Traits::to_int_type(__delim); 1556*38fd1498Szrj const __int_type __eof = _Traits::eof(); 1557*38fd1498Szrj __int_type __c = __in.rdbuf()->sgetc(); 1558*38fd1498Szrj 1559*38fd1498Szrj while (__extracted < __n 1560*38fd1498Szrj && !_Traits::eq_int_type(__c, __eof) 1561*38fd1498Szrj && !_Traits::eq_int_type(__c, __idelim)) 1562*38fd1498Szrj { 1563*38fd1498Szrj __str += _Traits::to_char_type(__c); 1564*38fd1498Szrj ++__extracted; 1565*38fd1498Szrj __c = __in.rdbuf()->snextc(); 1566*38fd1498Szrj } 1567*38fd1498Szrj 1568*38fd1498Szrj if (_Traits::eq_int_type(__c, __eof)) 1569*38fd1498Szrj __err |= __ios_base::eofbit; 1570*38fd1498Szrj else if (_Traits::eq_int_type(__c, __idelim)) 1571*38fd1498Szrj { 1572*38fd1498Szrj ++__extracted; 1573*38fd1498Szrj __in.rdbuf()->sbumpc(); 1574*38fd1498Szrj } 1575*38fd1498Szrj else 1576*38fd1498Szrj __err |= __ios_base::failbit; 1577*38fd1498Szrj } 1578*38fd1498Szrj __catch(__cxxabiv1::__forced_unwind&) 1579*38fd1498Szrj { 1580*38fd1498Szrj __in._M_setstate(__ios_base::badbit); 1581*38fd1498Szrj __throw_exception_again; 1582*38fd1498Szrj } 1583*38fd1498Szrj __catch(...) 1584*38fd1498Szrj { 1585*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1586*38fd1498Szrj // 91. Description of operator>> and getline() for string<> 1587*38fd1498Szrj // might cause endless loop 1588*38fd1498Szrj __in._M_setstate(__ios_base::badbit); 1589*38fd1498Szrj } 1590*38fd1498Szrj } 1591*38fd1498Szrj if (!__extracted) 1592*38fd1498Szrj __err |= __ios_base::failbit; 1593*38fd1498Szrj if (__err) 1594*38fd1498Szrj __in.setstate(__err); 1595*38fd1498Szrj return __in; 1596*38fd1498Szrj } 1597*38fd1498Szrj 1598*38fd1498Szrj // Inhibit implicit instantiations for required instantiations, 1599*38fd1498Szrj // which are defined via explicit instantiations elsewhere. 1600*38fd1498Szrj #if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L 1601*38fd1498Szrj extern template class basic_string<char>; 1602*38fd1498Szrj extern template 1603*38fd1498Szrj basic_istream<char>& 1604*38fd1498Szrj operator>>(basic_istream<char>&, string&); 1605*38fd1498Szrj extern template 1606*38fd1498Szrj basic_ostream<char>& 1607*38fd1498Szrj operator<<(basic_ostream<char>&, const string&); 1608*38fd1498Szrj extern template 1609*38fd1498Szrj basic_istream<char>& 1610*38fd1498Szrj getline(basic_istream<char>&, string&, char); 1611*38fd1498Szrj extern template 1612*38fd1498Szrj basic_istream<char>& 1613*38fd1498Szrj getline(basic_istream<char>&, string&); 1614*38fd1498Szrj 1615*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 1616*38fd1498Szrj extern template class basic_string<wchar_t>; 1617*38fd1498Szrj extern template 1618*38fd1498Szrj basic_istream<wchar_t>& 1619*38fd1498Szrj operator>>(basic_istream<wchar_t>&, wstring&); 1620*38fd1498Szrj extern template 1621*38fd1498Szrj basic_ostream<wchar_t>& 1622*38fd1498Szrj operator<<(basic_ostream<wchar_t>&, const wstring&); 1623*38fd1498Szrj extern template 1624*38fd1498Szrj basic_istream<wchar_t>& 1625*38fd1498Szrj getline(basic_istream<wchar_t>&, wstring&, wchar_t); 1626*38fd1498Szrj extern template 1627*38fd1498Szrj basic_istream<wchar_t>& 1628*38fd1498Szrj getline(basic_istream<wchar_t>&, wstring&); 1629*38fd1498Szrj #endif 1630*38fd1498Szrj #endif 1631*38fd1498Szrj 1632*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 1633*38fd1498Szrj } // namespace std 1634*38fd1498Szrj 1635*38fd1498Szrj #endif 1636