138fd1498Szrj // Components for manipulating sequences of characters -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj /** @file bits/basic_string.tcc 2638fd1498Szrj * This is an internal header file, included by other library headers. 2738fd1498Szrj * Do not attempt to use it directly. @headername{string} 2838fd1498Szrj */ 2938fd1498Szrj 3038fd1498Szrj // 3138fd1498Szrj // ISO C++ 14882: 21 Strings library 3238fd1498Szrj // 3338fd1498Szrj 3438fd1498Szrj // Written by Jason Merrill based upon the specification by Takanori Adachi 3538fd1498Szrj // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 3638fd1498Szrj // Non-reference-counted implementation written by Paolo Carlini and 3738fd1498Szrj // updated by Jonathan Wakely for ISO-14882-2011. 3838fd1498Szrj 3938fd1498Szrj #ifndef _BASIC_STRING_TCC 4038fd1498Szrj #define _BASIC_STRING_TCC 1 4138fd1498Szrj 4238fd1498Szrj #pragma GCC system_header 4338fd1498Szrj 4438fd1498Szrj #include <bits/cxxabi_forced.h> 4538fd1498Szrj 4638fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 4738fd1498Szrj { 4838fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 4938fd1498Szrj 5038fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI 5138fd1498Szrj 5238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 5338fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 5438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::npos; 5538fd1498Szrj 5638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 5738fd1498Szrj void 5838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: swap(basic_string & __s)5938fd1498Szrj swap(basic_string& __s) _GLIBCXX_NOEXCEPT 6038fd1498Szrj { 6138fd1498Szrj if (this == &__s) 6238fd1498Szrj return; 6338fd1498Szrj 6438fd1498Szrj _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); 6538fd1498Szrj 6638fd1498Szrj if (_M_is_local()) 6738fd1498Szrj if (__s._M_is_local()) 6838fd1498Szrj { 6938fd1498Szrj if (length() && __s.length()) 7038fd1498Szrj { 7138fd1498Szrj _CharT __tmp_data[_S_local_capacity + 1]; 7238fd1498Szrj traits_type::copy(__tmp_data, __s._M_local_buf, 7338fd1498Szrj _S_local_capacity + 1); 7438fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 7538fd1498Szrj _S_local_capacity + 1); 7638fd1498Szrj traits_type::copy(_M_local_buf, __tmp_data, 7738fd1498Szrj _S_local_capacity + 1); 7838fd1498Szrj } 7938fd1498Szrj else if (__s.length()) 8038fd1498Szrj { 8138fd1498Szrj traits_type::copy(_M_local_buf, __s._M_local_buf, 8238fd1498Szrj _S_local_capacity + 1); 8338fd1498Szrj _M_length(__s.length()); 8438fd1498Szrj __s._M_set_length(0); 8538fd1498Szrj return; 8638fd1498Szrj } 8738fd1498Szrj else if (length()) 8838fd1498Szrj { 8938fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 9038fd1498Szrj _S_local_capacity + 1); 9138fd1498Szrj __s._M_length(length()); 9238fd1498Szrj _M_set_length(0); 9338fd1498Szrj return; 9438fd1498Szrj } 9538fd1498Szrj } 9638fd1498Szrj else 9738fd1498Szrj { 9838fd1498Szrj const size_type __tmp_capacity = __s._M_allocated_capacity; 9938fd1498Szrj traits_type::copy(__s._M_local_buf, _M_local_buf, 10038fd1498Szrj _S_local_capacity + 1); 10138fd1498Szrj _M_data(__s._M_data()); 10238fd1498Szrj __s._M_data(__s._M_local_buf); 10338fd1498Szrj _M_capacity(__tmp_capacity); 10438fd1498Szrj } 10538fd1498Szrj else 10638fd1498Szrj { 10738fd1498Szrj const size_type __tmp_capacity = _M_allocated_capacity; 10838fd1498Szrj if (__s._M_is_local()) 10938fd1498Szrj { 11038fd1498Szrj traits_type::copy(_M_local_buf, __s._M_local_buf, 11138fd1498Szrj _S_local_capacity + 1); 11238fd1498Szrj __s._M_data(_M_data()); 11338fd1498Szrj _M_data(_M_local_buf); 11438fd1498Szrj } 11538fd1498Szrj else 11638fd1498Szrj { 11738fd1498Szrj pointer __tmp_ptr = _M_data(); 11838fd1498Szrj _M_data(__s._M_data()); 11938fd1498Szrj __s._M_data(__tmp_ptr); 12038fd1498Szrj _M_capacity(__s._M_allocated_capacity); 12138fd1498Szrj } 12238fd1498Szrj __s._M_capacity(__tmp_capacity); 12338fd1498Szrj } 12438fd1498Szrj 12538fd1498Szrj const size_type __tmp_length = length(); 12638fd1498Szrj _M_length(__s.length()); 12738fd1498Szrj __s._M_length(__tmp_length); 12838fd1498Szrj } 12938fd1498Szrj 13038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 13138fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::pointer 13238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_create(size_type & __capacity,size_type __old_capacity)13338fd1498Szrj _M_create(size_type& __capacity, size_type __old_capacity) 13438fd1498Szrj { 13538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 13638fd1498Szrj // 83. String::npos vs. string::max_size() 13738fd1498Szrj if (__capacity > max_size()) 13838fd1498Szrj std::__throw_length_error(__N("basic_string::_M_create")); 13938fd1498Szrj 14038fd1498Szrj // The below implements an exponential growth policy, necessary to 14138fd1498Szrj // meet amortized linear time requirements of the library: see 14238fd1498Szrj // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 14338fd1498Szrj if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 14438fd1498Szrj { 14538fd1498Szrj __capacity = 2 * __old_capacity; 14638fd1498Szrj // Never allocate a string bigger than max_size. 14738fd1498Szrj if (__capacity > max_size()) 14838fd1498Szrj __capacity = max_size(); 14938fd1498Szrj } 15038fd1498Szrj 15138fd1498Szrj // NB: Need an array of char_type[__capacity], plus a terminating 15238fd1498Szrj // null char_type() element. 15338fd1498Szrj return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); 15438fd1498Szrj } 15538fd1498Szrj 15638fd1498Szrj // NB: This is the special case for Input Iterators, used in 15738fd1498Szrj // istreambuf_iterators, etc. 15838fd1498Szrj // Input Iterators have a cost structure very different from 15938fd1498Szrj // pointers, calling for a different coding style. 16038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 16138fd1498Szrj template<typename _InIterator> 16238fd1498Szrj void 16338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)16438fd1498Szrj _M_construct(_InIterator __beg, _InIterator __end, 16538fd1498Szrj std::input_iterator_tag) 16638fd1498Szrj { 16738fd1498Szrj size_type __len = 0; 16838fd1498Szrj size_type __capacity = size_type(_S_local_capacity); 16938fd1498Szrj 17038fd1498Szrj while (__beg != __end && __len < __capacity) 17138fd1498Szrj { 17238fd1498Szrj _M_data()[__len++] = *__beg; 17338fd1498Szrj ++__beg; 17438fd1498Szrj } 17538fd1498Szrj 17638fd1498Szrj __try 17738fd1498Szrj { 17838fd1498Szrj while (__beg != __end) 17938fd1498Szrj { 18038fd1498Szrj if (__len == __capacity) 18138fd1498Szrj { 18238fd1498Szrj // Allocate more space. 18338fd1498Szrj __capacity = __len + 1; 18438fd1498Szrj pointer __another = _M_create(__capacity, __len); 18538fd1498Szrj this->_S_copy(__another, _M_data(), __len); 18638fd1498Szrj _M_dispose(); 18738fd1498Szrj _M_data(__another); 18838fd1498Szrj _M_capacity(__capacity); 18938fd1498Szrj } 19038fd1498Szrj _M_data()[__len++] = *__beg; 19138fd1498Szrj ++__beg; 19238fd1498Szrj } 19338fd1498Szrj } 19438fd1498Szrj __catch(...) 19538fd1498Szrj { 19638fd1498Szrj _M_dispose(); 19738fd1498Szrj __throw_exception_again; 19838fd1498Szrj } 19938fd1498Szrj 20038fd1498Szrj _M_set_length(__len); 20138fd1498Szrj } 20238fd1498Szrj 20338fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 20438fd1498Szrj template<typename _InIterator> 20538fd1498Szrj void 20638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)20738fd1498Szrj _M_construct(_InIterator __beg, _InIterator __end, 20838fd1498Szrj std::forward_iterator_tag) 20938fd1498Szrj { 21038fd1498Szrj // NB: Not required, but considered best practice. 21138fd1498Szrj if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 21238fd1498Szrj std::__throw_logic_error(__N("basic_string::" 21338fd1498Szrj "_M_construct null not valid")); 21438fd1498Szrj 21538fd1498Szrj size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); 21638fd1498Szrj 21738fd1498Szrj if (__dnew > size_type(_S_local_capacity)) 21838fd1498Szrj { 21938fd1498Szrj _M_data(_M_create(__dnew, size_type(0))); 22038fd1498Szrj _M_capacity(__dnew); 22138fd1498Szrj } 22238fd1498Szrj 22338fd1498Szrj // Check for out_of_range and length_error exceptions. 22438fd1498Szrj __try 22538fd1498Szrj { this->_S_copy_chars(_M_data(), __beg, __end); } 22638fd1498Szrj __catch(...) 22738fd1498Szrj { 22838fd1498Szrj _M_dispose(); 22938fd1498Szrj __throw_exception_again; 23038fd1498Szrj } 23138fd1498Szrj 23238fd1498Szrj _M_set_length(__dnew); 23338fd1498Szrj } 23438fd1498Szrj 23538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 23638fd1498Szrj void 23738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_construct(size_type __n,_CharT __c)23838fd1498Szrj _M_construct(size_type __n, _CharT __c) 23938fd1498Szrj { 24038fd1498Szrj if (__n > size_type(_S_local_capacity)) 24138fd1498Szrj { 24238fd1498Szrj _M_data(_M_create(__n, size_type(0))); 24338fd1498Szrj _M_capacity(__n); 24438fd1498Szrj } 24538fd1498Szrj 24638fd1498Szrj if (__n) 24738fd1498Szrj this->_S_assign(_M_data(), __n, __c); 24838fd1498Szrj 24938fd1498Szrj _M_set_length(__n); 25038fd1498Szrj } 25138fd1498Szrj 25238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 25338fd1498Szrj void 25438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_assign(const basic_string & __str)25538fd1498Szrj _M_assign(const basic_string& __str) 25638fd1498Szrj { 25738fd1498Szrj if (this != &__str) 25838fd1498Szrj { 25938fd1498Szrj const size_type __rsize = __str.length(); 26038fd1498Szrj const size_type __capacity = capacity(); 26138fd1498Szrj 26238fd1498Szrj if (__rsize > __capacity) 26338fd1498Szrj { 26438fd1498Szrj size_type __new_capacity = __rsize; 26538fd1498Szrj pointer __tmp = _M_create(__new_capacity, __capacity); 26638fd1498Szrj _M_dispose(); 26738fd1498Szrj _M_data(__tmp); 26838fd1498Szrj _M_capacity(__new_capacity); 26938fd1498Szrj } 27038fd1498Szrj 27138fd1498Szrj if (__rsize) 27238fd1498Szrj this->_S_copy(_M_data(), __str._M_data(), __rsize); 27338fd1498Szrj 27438fd1498Szrj _M_set_length(__rsize); 27538fd1498Szrj } 27638fd1498Szrj } 27738fd1498Szrj 27838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 27938fd1498Szrj void 28038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res)28138fd1498Szrj reserve(size_type __res) 28238fd1498Szrj { 28338fd1498Szrj // Make sure we don't shrink below the current size. 28438fd1498Szrj if (__res < length()) 28538fd1498Szrj __res = length(); 28638fd1498Szrj 28738fd1498Szrj const size_type __capacity = capacity(); 28838fd1498Szrj if (__res != __capacity) 28938fd1498Szrj { 29038fd1498Szrj if (__res > __capacity 29138fd1498Szrj || __res > size_type(_S_local_capacity)) 29238fd1498Szrj { 29338fd1498Szrj pointer __tmp = _M_create(__res, __capacity); 29438fd1498Szrj this->_S_copy(__tmp, _M_data(), length() + 1); 29538fd1498Szrj _M_dispose(); 29638fd1498Szrj _M_data(__tmp); 29738fd1498Szrj _M_capacity(__res); 29838fd1498Szrj } 29938fd1498Szrj else if (!_M_is_local()) 30038fd1498Szrj { 30138fd1498Szrj this->_S_copy(_M_local_data(), _M_data(), length() + 1); 30238fd1498Szrj _M_destroy(__capacity); 30338fd1498Szrj _M_data(_M_local_data()); 30438fd1498Szrj } 30538fd1498Szrj } 30638fd1498Szrj } 30738fd1498Szrj 30838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 30938fd1498Szrj void 31038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos,size_type __len1,const _CharT * __s,size_type __len2)31138fd1498Szrj _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 31238fd1498Szrj size_type __len2) 31338fd1498Szrj { 31438fd1498Szrj const size_type __how_much = length() - __pos - __len1; 31538fd1498Szrj 31638fd1498Szrj size_type __new_capacity = length() + __len2 - __len1; 31738fd1498Szrj pointer __r = _M_create(__new_capacity, capacity()); 31838fd1498Szrj 31938fd1498Szrj if (__pos) 32038fd1498Szrj this->_S_copy(__r, _M_data(), __pos); 32138fd1498Szrj if (__s && __len2) 32238fd1498Szrj this->_S_copy(__r + __pos, __s, __len2); 32338fd1498Szrj if (__how_much) 32438fd1498Szrj this->_S_copy(__r + __pos + __len2, 32538fd1498Szrj _M_data() + __pos + __len1, __how_much); 32638fd1498Szrj 32738fd1498Szrj _M_dispose(); 32838fd1498Szrj _M_data(__r); 32938fd1498Szrj _M_capacity(__new_capacity); 33038fd1498Szrj } 33138fd1498Szrj 33238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 33338fd1498Szrj void 33438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos,size_type __n)33538fd1498Szrj _M_erase(size_type __pos, size_type __n) 33638fd1498Szrj { 33738fd1498Szrj const size_type __how_much = length() - __pos - __n; 33838fd1498Szrj 33938fd1498Szrj if (__how_much && __n) 34038fd1498Szrj this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); 34138fd1498Szrj 34238fd1498Szrj _M_set_length(length() - __n); 34338fd1498Szrj } 34438fd1498Szrj 34538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 34638fd1498Szrj void 34738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n,_CharT __c)34838fd1498Szrj resize(size_type __n, _CharT __c) 34938fd1498Szrj { 35038fd1498Szrj const size_type __size = this->size(); 35138fd1498Szrj if (__size < __n) 35238fd1498Szrj this->append(__n - __size, __c); 35338fd1498Szrj else if (__n < __size) 35438fd1498Szrj this->_M_set_length(__n); 35538fd1498Szrj } 35638fd1498Szrj 35738fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 35838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 35938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_append(const _CharT * __s,size_type __n)36038fd1498Szrj _M_append(const _CharT* __s, size_type __n) 36138fd1498Szrj { 36238fd1498Szrj const size_type __len = __n + this->size(); 36338fd1498Szrj 36438fd1498Szrj if (__len <= this->capacity()) 36538fd1498Szrj { 36638fd1498Szrj if (__n) 36738fd1498Szrj this->_S_copy(this->_M_data() + this->size(), __s, __n); 36838fd1498Szrj } 36938fd1498Szrj else 37038fd1498Szrj this->_M_mutate(this->size(), size_type(0), __s, __n); 37138fd1498Szrj 37238fd1498Szrj this->_M_set_length(__len); 37338fd1498Szrj return *this; 37438fd1498Szrj } 37538fd1498Szrj 37638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 37738fd1498Szrj template<typename _InputIterator> 37838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 37938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_replace_dispatch(const_iterator __i1,const_iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)38038fd1498Szrj _M_replace_dispatch(const_iterator __i1, const_iterator __i2, 38138fd1498Szrj _InputIterator __k1, _InputIterator __k2, 38238fd1498Szrj std::__false_type) 38338fd1498Szrj { 38438fd1498Szrj const basic_string __s(__k1, __k2); 38538fd1498Szrj const size_type __n1 = __i2 - __i1; 38638fd1498Szrj return _M_replace(__i1 - begin(), __n1, __s._M_data(), 38738fd1498Szrj __s.size()); 38838fd1498Szrj } 38938fd1498Szrj 39038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 39138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 39238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)39338fd1498Szrj _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 39438fd1498Szrj _CharT __c) 39538fd1498Szrj { 39638fd1498Szrj _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 39738fd1498Szrj 39838fd1498Szrj const size_type __old_size = this->size(); 39938fd1498Szrj const size_type __new_size = __old_size + __n2 - __n1; 40038fd1498Szrj 40138fd1498Szrj if (__new_size <= this->capacity()) 40238fd1498Szrj { 40338fd1498Szrj pointer __p = this->_M_data() + __pos1; 40438fd1498Szrj 40538fd1498Szrj const size_type __how_much = __old_size - __pos1 - __n1; 40638fd1498Szrj if (__how_much && __n1 != __n2) 40738fd1498Szrj this->_S_move(__p + __n2, __p + __n1, __how_much); 40838fd1498Szrj } 40938fd1498Szrj else 41038fd1498Szrj this->_M_mutate(__pos1, __n1, 0, __n2); 41138fd1498Szrj 41238fd1498Szrj if (__n2) 41338fd1498Szrj this->_S_assign(this->_M_data() + __pos1, __n2, __c); 41438fd1498Szrj 41538fd1498Szrj this->_M_set_length(__new_size); 41638fd1498Szrj return *this; 41738fd1498Szrj } 41838fd1498Szrj 41938fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 42038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 42138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: _M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)42238fd1498Szrj _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 42338fd1498Szrj const size_type __len2) 42438fd1498Szrj { 42538fd1498Szrj _M_check_length(__len1, __len2, "basic_string::_M_replace"); 42638fd1498Szrj 42738fd1498Szrj const size_type __old_size = this->size(); 42838fd1498Szrj const size_type __new_size = __old_size + __len2 - __len1; 42938fd1498Szrj 43038fd1498Szrj if (__new_size <= this->capacity()) 43138fd1498Szrj { 43238fd1498Szrj pointer __p = this->_M_data() + __pos; 43338fd1498Szrj 43438fd1498Szrj const size_type __how_much = __old_size - __pos - __len1; 43538fd1498Szrj if (_M_disjunct(__s)) 43638fd1498Szrj { 43738fd1498Szrj if (__how_much && __len1 != __len2) 43838fd1498Szrj this->_S_move(__p + __len2, __p + __len1, __how_much); 43938fd1498Szrj if (__len2) 44038fd1498Szrj this->_S_copy(__p, __s, __len2); 44138fd1498Szrj } 44238fd1498Szrj else 44338fd1498Szrj { 44438fd1498Szrj // Work in-place. 44538fd1498Szrj if (__len2 && __len2 <= __len1) 44638fd1498Szrj this->_S_move(__p, __s, __len2); 44738fd1498Szrj if (__how_much && __len1 != __len2) 44838fd1498Szrj this->_S_move(__p + __len2, __p + __len1, __how_much); 44938fd1498Szrj if (__len2 > __len1) 45038fd1498Szrj { 45138fd1498Szrj if (__s + __len2 <= __p + __len1) 45238fd1498Szrj this->_S_move(__p, __s, __len2); 45338fd1498Szrj else if (__s >= __p + __len1) 45438fd1498Szrj this->_S_copy(__p, __s + __len2 - __len1, __len2); 45538fd1498Szrj else 45638fd1498Szrj { 45738fd1498Szrj const size_type __nleft = (__p + __len1) - __s; 45838fd1498Szrj this->_S_move(__p, __s, __nleft); 45938fd1498Szrj this->_S_copy(__p + __nleft, __p + __len2, 46038fd1498Szrj __len2 - __nleft); 46138fd1498Szrj } 46238fd1498Szrj } 46338fd1498Szrj } 46438fd1498Szrj } 46538fd1498Szrj else 46638fd1498Szrj this->_M_mutate(__pos, __len1, __s, __len2); 46738fd1498Szrj 46838fd1498Szrj this->_M_set_length(__new_size); 46938fd1498Szrj return *this; 47038fd1498Szrj } 47138fd1498Szrj 47238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 47338fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 47438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT * __s,size_type __n,size_type __pos) const47538fd1498Szrj copy(_CharT* __s, size_type __n, size_type __pos) const 47638fd1498Szrj { 47738fd1498Szrj _M_check(__pos, "basic_string::copy"); 47838fd1498Szrj __n = _M_limit(__pos, __n); 47938fd1498Szrj __glibcxx_requires_string_len(__s, __n); 48038fd1498Szrj if (__n) 48138fd1498Szrj _S_copy(__s, _M_data() + __pos, __n); 48238fd1498Szrj // 21.3.5.7 par 3: do not append null. (good.) 48338fd1498Szrj return __n; 48438fd1498Szrj } 48538fd1498Szrj 48638fd1498Szrj #else // !_GLIBCXX_USE_CXX11_ABI 48738fd1498Szrj 48838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 48938fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 49038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 49138fd1498Szrj _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; 49238fd1498Szrj 49338fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 49438fd1498Szrj const _CharT 49538fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 49638fd1498Szrj _Rep::_S_terminal = _CharT(); 49738fd1498Szrj 49838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 49938fd1498Szrj const typename basic_string<_CharT, _Traits, _Alloc>::size_type 50038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::npos; 50138fd1498Szrj 50238fd1498Szrj // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) 50338fd1498Szrj // at static init time (before static ctors are run). 50438fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 50538fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 50638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ 50738fd1498Szrj (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / 50838fd1498Szrj sizeof(size_type)]; 50938fd1498Szrj 51038fd1498Szrj // NB: This is the special case for Input Iterators, used in 51138fd1498Szrj // istreambuf_iterators, etc. 51238fd1498Szrj // Input Iterators have a cost structure very different from 51338fd1498Szrj // pointers, calling for a different coding style. 51438fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 51538fd1498Szrj template<typename _InIterator> 51638fd1498Szrj _CharT* 51738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 51838fd1498Szrj _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 51938fd1498Szrj input_iterator_tag) 52038fd1498Szrj { 52138fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 52238fd1498Szrj if (__beg == __end && __a == _Alloc()) 52338fd1498Szrj return _S_empty_rep()._M_refdata(); 52438fd1498Szrj #endif 52538fd1498Szrj // Avoid reallocation for common case. 52638fd1498Szrj _CharT __buf[128]; 52738fd1498Szrj size_type __len = 0; 52838fd1498Szrj while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) 52938fd1498Szrj { 53038fd1498Szrj __buf[__len++] = *__beg; 53138fd1498Szrj ++__beg; 53238fd1498Szrj } 53338fd1498Szrj _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); 53438fd1498Szrj _M_copy(__r->_M_refdata(), __buf, __len); 53538fd1498Szrj __try 53638fd1498Szrj { 53738fd1498Szrj while (__beg != __end) 53838fd1498Szrj { 53938fd1498Szrj if (__len == __r->_M_capacity) 54038fd1498Szrj { 54138fd1498Szrj // Allocate more space. 54238fd1498Szrj _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); 54338fd1498Szrj _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); 54438fd1498Szrj __r->_M_destroy(__a); 54538fd1498Szrj __r = __another; 54638fd1498Szrj } 54738fd1498Szrj __r->_M_refdata()[__len++] = *__beg; 54838fd1498Szrj ++__beg; 54938fd1498Szrj } 55038fd1498Szrj } 55138fd1498Szrj __catch(...) 55238fd1498Szrj { 55338fd1498Szrj __r->_M_destroy(__a); 55438fd1498Szrj __throw_exception_again; 55538fd1498Szrj } 55638fd1498Szrj __r->_M_set_length_and_sharable(__len); 55738fd1498Szrj return __r->_M_refdata(); 55838fd1498Szrj } 55938fd1498Szrj 56038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 56138fd1498Szrj template <typename _InIterator> 56238fd1498Szrj _CharT* 56338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 56438fd1498Szrj _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 56538fd1498Szrj forward_iterator_tag) 56638fd1498Szrj { 56738fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 56838fd1498Szrj if (__beg == __end && __a == _Alloc()) 56938fd1498Szrj return _S_empty_rep()._M_refdata(); 57038fd1498Szrj #endif 57138fd1498Szrj // NB: Not required, but considered best practice. 57238fd1498Szrj if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) 57338fd1498Szrj __throw_logic_error(__N("basic_string::_S_construct null not valid")); 57438fd1498Szrj 57538fd1498Szrj const size_type __dnew = static_cast<size_type>(std::distance(__beg, 57638fd1498Szrj __end)); 57738fd1498Szrj // Check for out_of_range and length_error exceptions. 57838fd1498Szrj _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); 57938fd1498Szrj __try 58038fd1498Szrj { _S_copy_chars(__r->_M_refdata(), __beg, __end); } 58138fd1498Szrj __catch(...) 58238fd1498Szrj { 58338fd1498Szrj __r->_M_destroy(__a); 58438fd1498Szrj __throw_exception_again; 58538fd1498Szrj } 58638fd1498Szrj __r->_M_set_length_and_sharable(__dnew); 58738fd1498Szrj return __r->_M_refdata(); 58838fd1498Szrj } 58938fd1498Szrj 59038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 59138fd1498Szrj _CharT* 59238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 59338fd1498Szrj _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 59438fd1498Szrj { 59538fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 59638fd1498Szrj if (__n == 0 && __a == _Alloc()) 59738fd1498Szrj return _S_empty_rep()._M_refdata(); 59838fd1498Szrj #endif 59938fd1498Szrj // Check for out_of_range and length_error exceptions. 60038fd1498Szrj _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); 60138fd1498Szrj if (__n) 60238fd1498Szrj _M_assign(__r->_M_refdata(), __n, __c); 60338fd1498Szrj 60438fd1498Szrj __r->_M_set_length_and_sharable(__n); 60538fd1498Szrj return __r->_M_refdata(); 60638fd1498Szrj } 60738fd1498Szrj 60838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 60938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 61038fd1498Szrj basic_string(const basic_string& __str) 61138fd1498Szrj : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), 61238fd1498Szrj __str.get_allocator()), 61338fd1498Szrj __str.get_allocator()) 61438fd1498Szrj { } 61538fd1498Szrj 61638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 61738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 61838fd1498Szrj basic_string(const _Alloc& __a) 61938fd1498Szrj : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) 62038fd1498Szrj { } 62138fd1498Szrj 62238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 62338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 62438fd1498Szrj basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a) 62538fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 62638fd1498Szrj + __str._M_check(__pos, 62738fd1498Szrj "basic_string::basic_string"), 62838fd1498Szrj __str._M_data() + __str._M_limit(__pos, npos) 62938fd1498Szrj + __pos, __a), __a) 63038fd1498Szrj { } 63138fd1498Szrj 63238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 63338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 63438fd1498Szrj basic_string(const basic_string& __str, size_type __pos, size_type __n) 63538fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 63638fd1498Szrj + __str._M_check(__pos, 63738fd1498Szrj "basic_string::basic_string"), 63838fd1498Szrj __str._M_data() + __str._M_limit(__pos, __n) 63938fd1498Szrj + __pos, _Alloc()), _Alloc()) 64038fd1498Szrj { } 64138fd1498Szrj 64238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 64338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 64438fd1498Szrj basic_string(const basic_string& __str, size_type __pos, 64538fd1498Szrj size_type __n, const _Alloc& __a) 64638fd1498Szrj : _M_dataplus(_S_construct(__str._M_data() 64738fd1498Szrj + __str._M_check(__pos, 64838fd1498Szrj "basic_string::basic_string"), 64938fd1498Szrj __str._M_data() + __str._M_limit(__pos, __n) 65038fd1498Szrj + __pos, __a), __a) 65138fd1498Szrj { } 65238fd1498Szrj 65338fd1498Szrj // TBD: DPG annotate 65438fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 65538fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 65638fd1498Szrj basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) 65738fd1498Szrj : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) 65838fd1498Szrj { } 65938fd1498Szrj 66038fd1498Szrj // TBD: DPG annotate 66138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 66238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 66338fd1498Szrj basic_string(const _CharT* __s, const _Alloc& __a) 66438fd1498Szrj : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : 66538fd1498Szrj __s + npos, __a), __a) 66638fd1498Szrj { } 66738fd1498Szrj 66838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 66938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 67038fd1498Szrj basic_string(size_type __n, _CharT __c, const _Alloc& __a) 67138fd1498Szrj : _M_dataplus(_S_construct(__n, __c, __a), __a) 67238fd1498Szrj { } 67338fd1498Szrj 67438fd1498Szrj // TBD: DPG annotate 67538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 67638fd1498Szrj template<typename _InputIterator> 67738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 67838fd1498Szrj basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) 67938fd1498Szrj : _M_dataplus(_S_construct(__beg, __end, __a), __a) 68038fd1498Szrj { } 68138fd1498Szrj 68238fd1498Szrj #if __cplusplus >= 201103L 68338fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 68438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 68538fd1498Szrj basic_string(initializer_list<_CharT> __l, const _Alloc& __a) 68638fd1498Szrj : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a) 68738fd1498Szrj { } 68838fd1498Szrj #endif 68938fd1498Szrj 69038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 69138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 69238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 69338fd1498Szrj assign(const basic_string& __str) 69438fd1498Szrj { 69538fd1498Szrj if (_M_rep() != __str._M_rep()) 69638fd1498Szrj { 69738fd1498Szrj // XXX MT 69838fd1498Szrj const allocator_type __a = this->get_allocator(); 69938fd1498Szrj _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); 70038fd1498Szrj _M_rep()->_M_dispose(__a); 70138fd1498Szrj _M_data(__tmp); 70238fd1498Szrj } 70338fd1498Szrj return *this; 70438fd1498Szrj } 70538fd1498Szrj 70638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 70738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 70838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 70938fd1498Szrj assign(const _CharT* __s, size_type __n) 71038fd1498Szrj { 71138fd1498Szrj __glibcxx_requires_string_len(__s, __n); 71238fd1498Szrj _M_check_length(this->size(), __n, "basic_string::assign"); 71338fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 71438fd1498Szrj return _M_replace_safe(size_type(0), this->size(), __s, __n); 71538fd1498Szrj else 71638fd1498Szrj { 71738fd1498Szrj // Work in-place. 71838fd1498Szrj const size_type __pos = __s - _M_data(); 71938fd1498Szrj if (__pos >= __n) 72038fd1498Szrj _M_copy(_M_data(), __s, __n); 72138fd1498Szrj else if (__pos) 72238fd1498Szrj _M_move(_M_data(), __s, __n); 72338fd1498Szrj _M_rep()->_M_set_length_and_sharable(__n); 72438fd1498Szrj return *this; 72538fd1498Szrj } 72638fd1498Szrj } 72738fd1498Szrj 72838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 72938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 73038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 73138fd1498Szrj append(size_type __n, _CharT __c) 73238fd1498Szrj { 73338fd1498Szrj if (__n) 73438fd1498Szrj { 73538fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::append"); 73638fd1498Szrj const size_type __len = __n + this->size(); 73738fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 73838fd1498Szrj this->reserve(__len); 73938fd1498Szrj _M_assign(_M_data() + this->size(), __n, __c); 74038fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 74138fd1498Szrj } 74238fd1498Szrj return *this; 74338fd1498Szrj } 74438fd1498Szrj 74538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 74638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 74738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 74838fd1498Szrj append(const _CharT* __s, size_type __n) 74938fd1498Szrj { 75038fd1498Szrj __glibcxx_requires_string_len(__s, __n); 75138fd1498Szrj if (__n) 75238fd1498Szrj { 75338fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::append"); 75438fd1498Szrj const size_type __len = __n + this->size(); 75538fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 75638fd1498Szrj { 75738fd1498Szrj if (_M_disjunct(__s)) 75838fd1498Szrj this->reserve(__len); 75938fd1498Szrj else 76038fd1498Szrj { 76138fd1498Szrj const size_type __off = __s - _M_data(); 76238fd1498Szrj this->reserve(__len); 76338fd1498Szrj __s = _M_data() + __off; 76438fd1498Szrj } 76538fd1498Szrj } 76638fd1498Szrj _M_copy(_M_data() + this->size(), __s, __n); 76738fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 76838fd1498Szrj } 76938fd1498Szrj return *this; 77038fd1498Szrj } 77138fd1498Szrj 77238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 77338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 77438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 77538fd1498Szrj append(const basic_string& __str) 77638fd1498Szrj { 77738fd1498Szrj const size_type __size = __str.size(); 77838fd1498Szrj if (__size) 77938fd1498Szrj { 78038fd1498Szrj const size_type __len = __size + this->size(); 78138fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 78238fd1498Szrj this->reserve(__len); 78338fd1498Szrj _M_copy(_M_data() + this->size(), __str._M_data(), __size); 78438fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 78538fd1498Szrj } 78638fd1498Szrj return *this; 78738fd1498Szrj } 78838fd1498Szrj 78938fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 79038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 79138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 79238fd1498Szrj append(const basic_string& __str, size_type __pos, size_type __n) 79338fd1498Szrj { 79438fd1498Szrj __str._M_check(__pos, "basic_string::append"); 79538fd1498Szrj __n = __str._M_limit(__pos, __n); 79638fd1498Szrj if (__n) 79738fd1498Szrj { 79838fd1498Szrj const size_type __len = __n + this->size(); 79938fd1498Szrj if (__len > this->capacity() || _M_rep()->_M_is_shared()) 80038fd1498Szrj this->reserve(__len); 80138fd1498Szrj _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); 80238fd1498Szrj _M_rep()->_M_set_length_and_sharable(__len); 80338fd1498Szrj } 80438fd1498Szrj return *this; 80538fd1498Szrj } 80638fd1498Szrj 80738fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 80838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 80938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 81038fd1498Szrj insert(size_type __pos, const _CharT* __s, size_type __n) 81138fd1498Szrj { 81238fd1498Szrj __glibcxx_requires_string_len(__s, __n); 81338fd1498Szrj _M_check(__pos, "basic_string::insert"); 81438fd1498Szrj _M_check_length(size_type(0), __n, "basic_string::insert"); 81538fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 81638fd1498Szrj return _M_replace_safe(__pos, size_type(0), __s, __n); 81738fd1498Szrj else 81838fd1498Szrj { 81938fd1498Szrj // Work in-place. 82038fd1498Szrj const size_type __off = __s - _M_data(); 82138fd1498Szrj _M_mutate(__pos, 0, __n); 82238fd1498Szrj __s = _M_data() + __off; 82338fd1498Szrj _CharT* __p = _M_data() + __pos; 82438fd1498Szrj if (__s + __n <= __p) 82538fd1498Szrj _M_copy(__p, __s, __n); 82638fd1498Szrj else if (__s >= __p) 82738fd1498Szrj _M_copy(__p, __s + __n, __n); 82838fd1498Szrj else 82938fd1498Szrj { 83038fd1498Szrj const size_type __nleft = __p - __s; 83138fd1498Szrj _M_copy(__p, __s, __nleft); 83238fd1498Szrj _M_copy(__p + __nleft, __p + __n, __n - __nleft); 83338fd1498Szrj } 83438fd1498Szrj return *this; 83538fd1498Szrj } 83638fd1498Szrj } 83738fd1498Szrj 83838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 83938fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::iterator 84038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 84138fd1498Szrj erase(iterator __first, iterator __last) 84238fd1498Szrj { 84338fd1498Szrj _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last 84438fd1498Szrj && __last <= _M_iend()); 84538fd1498Szrj 84638fd1498Szrj // NB: This isn't just an optimization (bail out early when 84738fd1498Szrj // there is nothing to do, really), it's also a correctness 84838fd1498Szrj // issue vs MT, see libstdc++/40518. 84938fd1498Szrj const size_type __size = __last - __first; 85038fd1498Szrj if (__size) 85138fd1498Szrj { 85238fd1498Szrj const size_type __pos = __first - _M_ibegin(); 85338fd1498Szrj _M_mutate(__pos, __size, size_type(0)); 85438fd1498Szrj _M_rep()->_M_set_leaked(); 85538fd1498Szrj return iterator(_M_data() + __pos); 85638fd1498Szrj } 85738fd1498Szrj else 85838fd1498Szrj return __first; 85938fd1498Szrj } 86038fd1498Szrj 86138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 86238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 86338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 86438fd1498Szrj replace(size_type __pos, size_type __n1, const _CharT* __s, 86538fd1498Szrj size_type __n2) 86638fd1498Szrj { 86738fd1498Szrj __glibcxx_requires_string_len(__s, __n2); 86838fd1498Szrj _M_check(__pos, "basic_string::replace"); 86938fd1498Szrj __n1 = _M_limit(__pos, __n1); 87038fd1498Szrj _M_check_length(__n1, __n2, "basic_string::replace"); 87138fd1498Szrj bool __left; 87238fd1498Szrj if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 87338fd1498Szrj return _M_replace_safe(__pos, __n1, __s, __n2); 87438fd1498Szrj else if ((__left = __s + __n2 <= _M_data() + __pos) 87538fd1498Szrj || _M_data() + __pos + __n1 <= __s) 87638fd1498Szrj { 87738fd1498Szrj // Work in-place: non-overlapping case. 87838fd1498Szrj size_type __off = __s - _M_data(); 87938fd1498Szrj __left ? __off : (__off += __n2 - __n1); 88038fd1498Szrj _M_mutate(__pos, __n1, __n2); 88138fd1498Szrj _M_copy(_M_data() + __pos, _M_data() + __off, __n2); 88238fd1498Szrj return *this; 88338fd1498Szrj } 88438fd1498Szrj else 88538fd1498Szrj { 88638fd1498Szrj // Todo: overlapping case. 88738fd1498Szrj const basic_string __tmp(__s, __n2); 88838fd1498Szrj return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); 88938fd1498Szrj } 89038fd1498Szrj } 89138fd1498Szrj 89238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 89338fd1498Szrj void 89438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 89538fd1498Szrj _M_destroy(const _Alloc& __a) throw () 89638fd1498Szrj { 89738fd1498Szrj const size_type __size = sizeof(_Rep_base) + 89838fd1498Szrj (this->_M_capacity + 1) * sizeof(_CharT); 89938fd1498Szrj _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); 90038fd1498Szrj } 90138fd1498Szrj 90238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 90338fd1498Szrj void 90438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 90538fd1498Szrj _M_leak_hard() 90638fd1498Szrj { 90738fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 90838fd1498Szrj if (_M_rep() == &_S_empty_rep()) 90938fd1498Szrj return; 91038fd1498Szrj #endif 91138fd1498Szrj if (_M_rep()->_M_is_shared()) 91238fd1498Szrj _M_mutate(0, 0, 0); 91338fd1498Szrj _M_rep()->_M_set_leaked(); 91438fd1498Szrj } 91538fd1498Szrj 91638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 91738fd1498Szrj void 91838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 91938fd1498Szrj _M_mutate(size_type __pos, size_type __len1, size_type __len2) 92038fd1498Szrj { 92138fd1498Szrj const size_type __old_size = this->size(); 92238fd1498Szrj const size_type __new_size = __old_size + __len2 - __len1; 92338fd1498Szrj const size_type __how_much = __old_size - __pos - __len1; 92438fd1498Szrj 92538fd1498Szrj if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) 92638fd1498Szrj { 92738fd1498Szrj // Must reallocate. 92838fd1498Szrj const allocator_type __a = get_allocator(); 92938fd1498Szrj _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); 93038fd1498Szrj 93138fd1498Szrj if (__pos) 93238fd1498Szrj _M_copy(__r->_M_refdata(), _M_data(), __pos); 93338fd1498Szrj if (__how_much) 93438fd1498Szrj _M_copy(__r->_M_refdata() + __pos + __len2, 93538fd1498Szrj _M_data() + __pos + __len1, __how_much); 93638fd1498Szrj 93738fd1498Szrj _M_rep()->_M_dispose(__a); 93838fd1498Szrj _M_data(__r->_M_refdata()); 93938fd1498Szrj } 94038fd1498Szrj else if (__how_much && __len1 != __len2) 94138fd1498Szrj { 94238fd1498Szrj // Work in-place. 94338fd1498Szrj _M_move(_M_data() + __pos + __len2, 94438fd1498Szrj _M_data() + __pos + __len1, __how_much); 94538fd1498Szrj } 94638fd1498Szrj _M_rep()->_M_set_length_and_sharable(__new_size); 94738fd1498Szrj } 94838fd1498Szrj 94938fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 95038fd1498Szrj void 95138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 95238fd1498Szrj reserve(size_type __res) 95338fd1498Szrj { 95438fd1498Szrj if (__res != this->capacity() || _M_rep()->_M_is_shared()) 95538fd1498Szrj { 95638fd1498Szrj // Make sure we don't shrink below the current size 95738fd1498Szrj if (__res < this->size()) 95838fd1498Szrj __res = this->size(); 95938fd1498Szrj const allocator_type __a = get_allocator(); 96038fd1498Szrj _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); 96138fd1498Szrj _M_rep()->_M_dispose(__a); 96238fd1498Szrj _M_data(__tmp); 96338fd1498Szrj } 96438fd1498Szrj } 96538fd1498Szrj 96638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 96738fd1498Szrj void 96838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 96938fd1498Szrj swap(basic_string& __s) 97038fd1498Szrj { 97138fd1498Szrj if (_M_rep()->_M_is_leaked()) 97238fd1498Szrj _M_rep()->_M_set_sharable(); 97338fd1498Szrj if (__s._M_rep()->_M_is_leaked()) 97438fd1498Szrj __s._M_rep()->_M_set_sharable(); 97538fd1498Szrj if (this->get_allocator() == __s.get_allocator()) 97638fd1498Szrj { 97738fd1498Szrj _CharT* __tmp = _M_data(); 97838fd1498Szrj _M_data(__s._M_data()); 97938fd1498Szrj __s._M_data(__tmp); 98038fd1498Szrj } 98138fd1498Szrj // The code below can usually be optimized away. 98238fd1498Szrj else 98338fd1498Szrj { 98438fd1498Szrj const basic_string __tmp1(_M_ibegin(), _M_iend(), 98538fd1498Szrj __s.get_allocator()); 98638fd1498Szrj const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 98738fd1498Szrj this->get_allocator()); 98838fd1498Szrj *this = __tmp2; 98938fd1498Szrj __s = __tmp1; 99038fd1498Szrj } 99138fd1498Szrj } 99238fd1498Szrj 99338fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 99438fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::_Rep* 99538fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 99638fd1498Szrj _S_create(size_type __capacity, size_type __old_capacity, 99738fd1498Szrj const _Alloc& __alloc) 99838fd1498Szrj { 99938fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 100038fd1498Szrj // 83. String::npos vs. string::max_size() 100138fd1498Szrj if (__capacity > _S_max_size) 100238fd1498Szrj __throw_length_error(__N("basic_string::_S_create")); 100338fd1498Szrj 100438fd1498Szrj // The standard places no restriction on allocating more memory 100538fd1498Szrj // than is strictly needed within this layer at the moment or as 100638fd1498Szrj // requested by an explicit application call to reserve(). 100738fd1498Szrj 100838fd1498Szrj // Many malloc implementations perform quite poorly when an 100938fd1498Szrj // application attempts to allocate memory in a stepwise fashion 101038fd1498Szrj // growing each allocation size by only 1 char. Additionally, 101138fd1498Szrj // it makes little sense to allocate less linear memory than the 101238fd1498Szrj // natural blocking size of the malloc implementation. 101338fd1498Szrj // Unfortunately, we would need a somewhat low-level calculation 101438fd1498Szrj // with tuned parameters to get this perfect for any particular 101538fd1498Szrj // malloc implementation. Fortunately, generalizations about 101638fd1498Szrj // common features seen among implementations seems to suffice. 101738fd1498Szrj 101838fd1498Szrj // __pagesize need not match the actual VM page size for good 101938fd1498Szrj // results in practice, thus we pick a common value on the low 102038fd1498Szrj // side. __malloc_header_size is an estimate of the amount of 102138fd1498Szrj // overhead per memory allocation (in practice seen N * sizeof 102238fd1498Szrj // (void*) where N is 0, 2 or 4). According to folklore, 102338fd1498Szrj // picking this value on the high side is better than 102438fd1498Szrj // low-balling it (especially when this algorithm is used with 102538fd1498Szrj // malloc implementations that allocate memory blocks rounded up 102638fd1498Szrj // to a size which is a power of 2). 102738fd1498Szrj const size_type __pagesize = 4096; 102838fd1498Szrj const size_type __malloc_header_size = 4 * sizeof(void*); 102938fd1498Szrj 103038fd1498Szrj // The below implements an exponential growth policy, necessary to 103138fd1498Szrj // meet amortized linear time requirements of the library: see 103238fd1498Szrj // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 103338fd1498Szrj // It's active for allocations requiring an amount of memory above 103438fd1498Szrj // system pagesize. This is consistent with the requirements of the 103538fd1498Szrj // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html 103638fd1498Szrj if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 103738fd1498Szrj __capacity = 2 * __old_capacity; 103838fd1498Szrj 103938fd1498Szrj // NB: Need an array of char_type[__capacity], plus a terminating 104038fd1498Szrj // null char_type() element, plus enough for the _Rep data structure. 104138fd1498Szrj // Whew. Seemingly so needy, yet so elemental. 104238fd1498Szrj size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 104338fd1498Szrj 104438fd1498Szrj const size_type __adj_size = __size + __malloc_header_size; 104538fd1498Szrj if (__adj_size > __pagesize && __capacity > __old_capacity) 104638fd1498Szrj { 104738fd1498Szrj const size_type __extra = __pagesize - __adj_size % __pagesize; 104838fd1498Szrj __capacity += __extra / sizeof(_CharT); 104938fd1498Szrj // Never allocate a string bigger than _S_max_size. 105038fd1498Szrj if (__capacity > _S_max_size) 105138fd1498Szrj __capacity = _S_max_size; 105238fd1498Szrj __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 105338fd1498Szrj } 105438fd1498Szrj 105538fd1498Szrj // NB: Might throw, but no worries about a leak, mate: _Rep() 105638fd1498Szrj // does not throw. 105738fd1498Szrj void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); 105838fd1498Szrj _Rep *__p = new (__place) _Rep; 105938fd1498Szrj __p->_M_capacity = __capacity; 106038fd1498Szrj // ABI compatibility - 3.4.x set in _S_create both 106138fd1498Szrj // _M_refcount and _M_length. All callers of _S_create 106238fd1498Szrj // in basic_string.tcc then set just _M_length. 106338fd1498Szrj // In 4.0.x and later both _M_refcount and _M_length 106438fd1498Szrj // are initialized in the callers, unfortunately we can 106538fd1498Szrj // have 3.4.x compiled code with _S_create callers inlined 106638fd1498Szrj // calling 4.0.x+ _S_create. 106738fd1498Szrj __p->_M_set_sharable(); 106838fd1498Szrj return __p; 106938fd1498Szrj } 107038fd1498Szrj 107138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 107238fd1498Szrj _CharT* 107338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>::_Rep:: 107438fd1498Szrj _M_clone(const _Alloc& __alloc, size_type __res) 107538fd1498Szrj { 107638fd1498Szrj // Requested capacity of the clone. 107738fd1498Szrj const size_type __requested_cap = this->_M_length + __res; 107838fd1498Szrj _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, 107938fd1498Szrj __alloc); 108038fd1498Szrj if (this->_M_length) 108138fd1498Szrj _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); 108238fd1498Szrj 108338fd1498Szrj __r->_M_set_length_and_sharable(this->_M_length); 108438fd1498Szrj return __r->_M_refdata(); 108538fd1498Szrj } 108638fd1498Szrj 108738fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 108838fd1498Szrj void 108938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 109038fd1498Szrj resize(size_type __n, _CharT __c) 109138fd1498Szrj { 109238fd1498Szrj const size_type __size = this->size(); 109338fd1498Szrj _M_check_length(__size, __n, "basic_string::resize"); 109438fd1498Szrj if (__size < __n) 109538fd1498Szrj this->append(__n - __size, __c); 109638fd1498Szrj else if (__n < __size) 109738fd1498Szrj this->erase(__n); 109838fd1498Szrj // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) 109938fd1498Szrj } 110038fd1498Szrj 110138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 110238fd1498Szrj template<typename _InputIterator> 110338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 110438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 110538fd1498Szrj _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 110638fd1498Szrj _InputIterator __k2, __false_type) 110738fd1498Szrj { 110838fd1498Szrj const basic_string __s(__k1, __k2); 110938fd1498Szrj const size_type __n1 = __i2 - __i1; 111038fd1498Szrj _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); 111138fd1498Szrj return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), 111238fd1498Szrj __s.size()); 111338fd1498Szrj } 111438fd1498Szrj 111538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 111638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 111738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 111838fd1498Szrj _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 111938fd1498Szrj _CharT __c) 112038fd1498Szrj { 112138fd1498Szrj _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 112238fd1498Szrj _M_mutate(__pos1, __n1, __n2); 112338fd1498Szrj if (__n2) 112438fd1498Szrj _M_assign(_M_data() + __pos1, __n2, __c); 112538fd1498Szrj return *this; 112638fd1498Szrj } 112738fd1498Szrj 112838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 112938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& 113038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 113138fd1498Szrj _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, 113238fd1498Szrj size_type __n2) 113338fd1498Szrj { 113438fd1498Szrj _M_mutate(__pos1, __n1, __n2); 113538fd1498Szrj if (__n2) 113638fd1498Szrj _M_copy(_M_data() + __pos1, __s, __n2); 113738fd1498Szrj return *this; 113838fd1498Szrj } 113938fd1498Szrj 114038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 114138fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 114238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: 114338fd1498Szrj copy(_CharT* __s, size_type __n, size_type __pos) const 114438fd1498Szrj { 114538fd1498Szrj _M_check(__pos, "basic_string::copy"); 114638fd1498Szrj __n = _M_limit(__pos, __n); 114738fd1498Szrj __glibcxx_requires_string_len(__s, __n); 114838fd1498Szrj if (__n) 114938fd1498Szrj _M_copy(__s, _M_data() + __pos, __n); 115038fd1498Szrj // 21.3.5.7 par 3: do not append null. (good.) 115138fd1498Szrj return __n; 115238fd1498Szrj } 115338fd1498Szrj #endif // !_GLIBCXX_USE_CXX11_ABI 115438fd1498Szrj 115538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 115638fd1498Szrj basic_string<_CharT, _Traits, _Alloc> operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)115738fd1498Szrj operator+(const _CharT* __lhs, 115838fd1498Szrj const basic_string<_CharT, _Traits, _Alloc>& __rhs) 115938fd1498Szrj { 116038fd1498Szrj __glibcxx_requires_string(__lhs); 116138fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 116238fd1498Szrj typedef typename __string_type::size_type __size_type; 116338fd1498Szrj const __size_type __len = _Traits::length(__lhs); 116438fd1498Szrj __string_type __str; 116538fd1498Szrj __str.reserve(__len + __rhs.size()); 116638fd1498Szrj __str.append(__lhs, __len); 116738fd1498Szrj __str.append(__rhs); 116838fd1498Szrj return __str; 116938fd1498Szrj } 117038fd1498Szrj 117138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 117238fd1498Szrj basic_string<_CharT, _Traits, _Alloc> operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)117338fd1498Szrj operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) 117438fd1498Szrj { 117538fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 117638fd1498Szrj typedef typename __string_type::size_type __size_type; 117738fd1498Szrj __string_type __str; 117838fd1498Szrj const __size_type __len = __rhs.size(); 117938fd1498Szrj __str.reserve(__len + 1); 118038fd1498Szrj __str.append(__size_type(1), __lhs); 118138fd1498Szrj __str.append(__rhs); 118238fd1498Szrj return __str; 118338fd1498Szrj } 118438fd1498Szrj 118538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 118638fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 118738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT * __s,size_type __pos,size_type __n) const118838fd1498Szrj find(const _CharT* __s, size_type __pos, size_type __n) const 118938fd1498Szrj _GLIBCXX_NOEXCEPT 119038fd1498Szrj { 119138fd1498Szrj __glibcxx_requires_string_len(__s, __n); 119238fd1498Szrj const size_type __size = this->size(); 119338fd1498Szrj 119438fd1498Szrj if (__n == 0) 119538fd1498Szrj return __pos <= __size ? __pos : npos; 119638fd1498Szrj if (__pos >= __size) 119738fd1498Szrj return npos; 119838fd1498Szrj 119938fd1498Szrj const _CharT __elem0 = __s[0]; 120038fd1498Szrj const _CharT* const __data = data(); 120138fd1498Szrj const _CharT* __first = __data + __pos; 120238fd1498Szrj const _CharT* const __last = __data + __size; 120338fd1498Szrj size_type __len = __size - __pos; 120438fd1498Szrj 120538fd1498Szrj while (__len >= __n) 120638fd1498Szrj { 120738fd1498Szrj // Find the first occurrence of __elem0: 120838fd1498Szrj __first = traits_type::find(__first, __len - __n + 1, __elem0); 120938fd1498Szrj if (!__first) 121038fd1498Szrj return npos; 121138fd1498Szrj // Compare the full strings from the first occurrence of __elem0. 121238fd1498Szrj // We already know that __first[0] == __s[0] but compare them again 121338fd1498Szrj // anyway because __s is probably aligned, which helps memcmp. 121438fd1498Szrj if (traits_type::compare(__first, __s, __n) == 0) 121538fd1498Szrj return __first - __data; 121638fd1498Szrj __len = __last - ++__first; 121738fd1498Szrj } 121838fd1498Szrj return npos; 121938fd1498Szrj } 122038fd1498Szrj 122138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 122238fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 122338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find(_CharT __c,size_type __pos) const122438fd1498Szrj find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 122538fd1498Szrj { 122638fd1498Szrj size_type __ret = npos; 122738fd1498Szrj const size_type __size = this->size(); 122838fd1498Szrj if (__pos < __size) 122938fd1498Szrj { 123038fd1498Szrj const _CharT* __data = _M_data(); 123138fd1498Szrj const size_type __n = __size - __pos; 123238fd1498Szrj const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 123338fd1498Szrj if (__p) 123438fd1498Szrj __ret = __p - __data; 123538fd1498Szrj } 123638fd1498Szrj return __ret; 123738fd1498Szrj } 123838fd1498Szrj 123938fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 124038fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 124138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT * __s,size_type __pos,size_type __n) const124238fd1498Szrj rfind(const _CharT* __s, size_type __pos, size_type __n) const 124338fd1498Szrj _GLIBCXX_NOEXCEPT 124438fd1498Szrj { 124538fd1498Szrj __glibcxx_requires_string_len(__s, __n); 124638fd1498Szrj const size_type __size = this->size(); 124738fd1498Szrj if (__n <= __size) 124838fd1498Szrj { 124938fd1498Szrj __pos = std::min(size_type(__size - __n), __pos); 125038fd1498Szrj const _CharT* __data = _M_data(); 125138fd1498Szrj do 125238fd1498Szrj { 125338fd1498Szrj if (traits_type::compare(__data + __pos, __s, __n) == 0) 125438fd1498Szrj return __pos; 125538fd1498Szrj } 125638fd1498Szrj while (__pos-- > 0); 125738fd1498Szrj } 125838fd1498Szrj return npos; 125938fd1498Szrj } 126038fd1498Szrj 126138fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 126238fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 126338fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: rfind(_CharT __c,size_type __pos) const126438fd1498Szrj rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 126538fd1498Szrj { 126638fd1498Szrj size_type __size = this->size(); 126738fd1498Szrj if (__size) 126838fd1498Szrj { 126938fd1498Szrj if (--__size > __pos) 127038fd1498Szrj __size = __pos; 127138fd1498Szrj for (++__size; __size-- > 0; ) 127238fd1498Szrj if (traits_type::eq(_M_data()[__size], __c)) 127338fd1498Szrj return __size; 127438fd1498Szrj } 127538fd1498Szrj return npos; 127638fd1498Szrj } 127738fd1498Szrj 127838fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 127938fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 128038fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT * __s,size_type __pos,size_type __n) const128138fd1498Szrj find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 128238fd1498Szrj _GLIBCXX_NOEXCEPT 128338fd1498Szrj { 128438fd1498Szrj __glibcxx_requires_string_len(__s, __n); 128538fd1498Szrj for (; __n && __pos < this->size(); ++__pos) 128638fd1498Szrj { 128738fd1498Szrj const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 128838fd1498Szrj if (__p) 128938fd1498Szrj return __pos; 129038fd1498Szrj } 129138fd1498Szrj return npos; 129238fd1498Szrj } 129338fd1498Szrj 129438fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 129538fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 129638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT * __s,size_type __pos,size_type __n) const129738fd1498Szrj find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 129838fd1498Szrj _GLIBCXX_NOEXCEPT 129938fd1498Szrj { 130038fd1498Szrj __glibcxx_requires_string_len(__s, __n); 130138fd1498Szrj size_type __size = this->size(); 130238fd1498Szrj if (__size && __n) 130338fd1498Szrj { 130438fd1498Szrj if (--__size > __pos) 130538fd1498Szrj __size = __pos; 130638fd1498Szrj do 130738fd1498Szrj { 130838fd1498Szrj if (traits_type::find(__s, __n, _M_data()[__size])) 130938fd1498Szrj return __size; 131038fd1498Szrj } 131138fd1498Szrj while (__size-- != 0); 131238fd1498Szrj } 131338fd1498Szrj return npos; 131438fd1498Szrj } 131538fd1498Szrj 131638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 131738fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 131838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const131938fd1498Szrj find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 132038fd1498Szrj _GLIBCXX_NOEXCEPT 132138fd1498Szrj { 132238fd1498Szrj __glibcxx_requires_string_len(__s, __n); 132338fd1498Szrj for (; __pos < this->size(); ++__pos) 132438fd1498Szrj if (!traits_type::find(__s, __n, _M_data()[__pos])) 132538fd1498Szrj return __pos; 132638fd1498Szrj return npos; 132738fd1498Szrj } 132838fd1498Szrj 132938fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 133038fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 133138fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(_CharT __c,size_type __pos) const133238fd1498Szrj find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 133338fd1498Szrj { 133438fd1498Szrj for (; __pos < this->size(); ++__pos) 133538fd1498Szrj if (!traits_type::eq(_M_data()[__pos], __c)) 133638fd1498Szrj return __pos; 133738fd1498Szrj return npos; 133838fd1498Szrj } 133938fd1498Szrj 134038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 134138fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 134238fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const134338fd1498Szrj find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 134438fd1498Szrj _GLIBCXX_NOEXCEPT 134538fd1498Szrj { 134638fd1498Szrj __glibcxx_requires_string_len(__s, __n); 134738fd1498Szrj size_type __size = this->size(); 134838fd1498Szrj if (__size) 134938fd1498Szrj { 135038fd1498Szrj if (--__size > __pos) 135138fd1498Szrj __size = __pos; 135238fd1498Szrj do 135338fd1498Szrj { 135438fd1498Szrj if (!traits_type::find(__s, __n, _M_data()[__size])) 135538fd1498Szrj return __size; 135638fd1498Szrj } 135738fd1498Szrj while (__size--); 135838fd1498Szrj } 135938fd1498Szrj return npos; 136038fd1498Szrj } 136138fd1498Szrj 136238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 136338fd1498Szrj typename basic_string<_CharT, _Traits, _Alloc>::size_type 136438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(_CharT __c,size_type __pos) const136538fd1498Szrj find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 136638fd1498Szrj { 136738fd1498Szrj size_type __size = this->size(); 136838fd1498Szrj if (__size) 136938fd1498Szrj { 137038fd1498Szrj if (--__size > __pos) 137138fd1498Szrj __size = __pos; 137238fd1498Szrj do 137338fd1498Szrj { 137438fd1498Szrj if (!traits_type::eq(_M_data()[__size], __c)) 137538fd1498Szrj return __size; 137638fd1498Szrj } 137738fd1498Szrj while (__size--); 137838fd1498Szrj } 137938fd1498Szrj return npos; 138038fd1498Szrj } 138138fd1498Szrj 138238fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 138338fd1498Szrj int 138438fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n,const basic_string & __str) const138538fd1498Szrj compare(size_type __pos, size_type __n, const basic_string& __str) const 138638fd1498Szrj { 138738fd1498Szrj _M_check(__pos, "basic_string::compare"); 138838fd1498Szrj __n = _M_limit(__pos, __n); 138938fd1498Szrj const size_type __osize = __str.size(); 139038fd1498Szrj const size_type __len = std::min(__n, __osize); 139138fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 139238fd1498Szrj if (!__r) 139338fd1498Szrj __r = _S_compare(__n, __osize); 139438fd1498Szrj return __r; 139538fd1498Szrj } 139638fd1498Szrj 139738fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 139838fd1498Szrj int 139938fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const140038fd1498Szrj compare(size_type __pos1, size_type __n1, const basic_string& __str, 140138fd1498Szrj size_type __pos2, size_type __n2) const 140238fd1498Szrj { 140338fd1498Szrj _M_check(__pos1, "basic_string::compare"); 140438fd1498Szrj __str._M_check(__pos2, "basic_string::compare"); 140538fd1498Szrj __n1 = _M_limit(__pos1, __n1); 140638fd1498Szrj __n2 = __str._M_limit(__pos2, __n2); 140738fd1498Szrj const size_type __len = std::min(__n1, __n2); 140838fd1498Szrj int __r = traits_type::compare(_M_data() + __pos1, 140938fd1498Szrj __str.data() + __pos2, __len); 141038fd1498Szrj if (!__r) 141138fd1498Szrj __r = _S_compare(__n1, __n2); 141238fd1498Szrj return __r; 141338fd1498Szrj } 141438fd1498Szrj 141538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 141638fd1498Szrj int 141738fd1498Szrj basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT * __s) const141838fd1498Szrj compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT 141938fd1498Szrj { 142038fd1498Szrj __glibcxx_requires_string(__s); 142138fd1498Szrj const size_type __size = this->size(); 142238fd1498Szrj const size_type __osize = traits_type::length(__s); 142338fd1498Szrj const size_type __len = std::min(__size, __osize); 142438fd1498Szrj int __r = traits_type::compare(_M_data(), __s, __len); 142538fd1498Szrj if (!__r) 142638fd1498Szrj __r = _S_compare(__size, __osize); 142738fd1498Szrj return __r; 142838fd1498Szrj } 142938fd1498Szrj 143038fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 143138fd1498Szrj int 143238fd1498Szrj basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s) const143338fd1498Szrj compare(size_type __pos, size_type __n1, const _CharT* __s) const 143438fd1498Szrj { 143538fd1498Szrj __glibcxx_requires_string(__s); 143638fd1498Szrj _M_check(__pos, "basic_string::compare"); 143738fd1498Szrj __n1 = _M_limit(__pos, __n1); 143838fd1498Szrj const size_type __osize = traits_type::length(__s); 143938fd1498Szrj const size_type __len = std::min(__n1, __osize); 144038fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __s, __len); 144138fd1498Szrj if (!__r) 144238fd1498Szrj __r = _S_compare(__n1, __osize); 144338fd1498Szrj return __r; 144438fd1498Szrj } 144538fd1498Szrj 144638fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 144738fd1498Szrj int 144838fd1498Szrj basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const144938fd1498Szrj compare(size_type __pos, size_type __n1, const _CharT* __s, 145038fd1498Szrj size_type __n2) const 145138fd1498Szrj { 145238fd1498Szrj __glibcxx_requires_string_len(__s, __n2); 145338fd1498Szrj _M_check(__pos, "basic_string::compare"); 145438fd1498Szrj __n1 = _M_limit(__pos, __n1); 145538fd1498Szrj const size_type __len = std::min(__n1, __n2); 145638fd1498Szrj int __r = traits_type::compare(_M_data() + __pos, __s, __len); 145738fd1498Szrj if (!__r) 145838fd1498Szrj __r = _S_compare(__n1, __n2); 145938fd1498Szrj return __r; 146038fd1498Szrj } 146138fd1498Szrj 146238fd1498Szrj // 21.3.7.9 basic_string::getline and operators 146338fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 146438fd1498Szrj basic_istream<_CharT, _Traits>& operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)146538fd1498Szrj operator>>(basic_istream<_CharT, _Traits>& __in, 146638fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& __str) 146738fd1498Szrj { 146838fd1498Szrj typedef basic_istream<_CharT, _Traits> __istream_type; 146938fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 147038fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 147138fd1498Szrj typedef typename __istream_type::int_type __int_type; 147238fd1498Szrj typedef typename __string_type::size_type __size_type; 147338fd1498Szrj typedef ctype<_CharT> __ctype_type; 147438fd1498Szrj typedef typename __ctype_type::ctype_base __ctype_base; 147538fd1498Szrj 147638fd1498Szrj __size_type __extracted = 0; 147738fd1498Szrj typename __ios_base::iostate __err = __ios_base::goodbit; 147838fd1498Szrj typename __istream_type::sentry __cerb(__in, false); 147938fd1498Szrj if (__cerb) 148038fd1498Szrj { 148138fd1498Szrj __try 148238fd1498Szrj { 148338fd1498Szrj // Avoid reallocation for common case. 148438fd1498Szrj __str.erase(); 148538fd1498Szrj _CharT __buf[128]; 148638fd1498Szrj __size_type __len = 0; 148738fd1498Szrj const streamsize __w = __in.width(); 148838fd1498Szrj const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 148938fd1498Szrj : __str.max_size(); 149038fd1498Szrj const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 149138fd1498Szrj const __int_type __eof = _Traits::eof(); 149238fd1498Szrj __int_type __c = __in.rdbuf()->sgetc(); 149338fd1498Szrj 149438fd1498Szrj while (__extracted < __n 149538fd1498Szrj && !_Traits::eq_int_type(__c, __eof) 149638fd1498Szrj && !__ct.is(__ctype_base::space, 149738fd1498Szrj _Traits::to_char_type(__c))) 149838fd1498Szrj { 149938fd1498Szrj if (__len == sizeof(__buf) / sizeof(_CharT)) 150038fd1498Szrj { 150138fd1498Szrj __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 150238fd1498Szrj __len = 0; 150338fd1498Szrj } 150438fd1498Szrj __buf[__len++] = _Traits::to_char_type(__c); 150538fd1498Szrj ++__extracted; 150638fd1498Szrj __c = __in.rdbuf()->snextc(); 150738fd1498Szrj } 150838fd1498Szrj __str.append(__buf, __len); 150938fd1498Szrj 151038fd1498Szrj if (_Traits::eq_int_type(__c, __eof)) 151138fd1498Szrj __err |= __ios_base::eofbit; 151238fd1498Szrj __in.width(0); 151338fd1498Szrj } 151438fd1498Szrj __catch(__cxxabiv1::__forced_unwind&) 151538fd1498Szrj { 151638fd1498Szrj __in._M_setstate(__ios_base::badbit); 151738fd1498Szrj __throw_exception_again; 151838fd1498Szrj } 151938fd1498Szrj __catch(...) 152038fd1498Szrj { 152138fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 152238fd1498Szrj // 91. Description of operator>> and getline() for string<> 152338fd1498Szrj // might cause endless loop 152438fd1498Szrj __in._M_setstate(__ios_base::badbit); 152538fd1498Szrj } 152638fd1498Szrj } 152738fd1498Szrj // 211. operator>>(istream&, string&) doesn't set failbit 152838fd1498Szrj if (!__extracted) 152938fd1498Szrj __err |= __ios_base::failbit; 153038fd1498Szrj if (__err) 153138fd1498Szrj __in.setstate(__err); 153238fd1498Szrj return __in; 153338fd1498Szrj } 153438fd1498Szrj 153538fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 153638fd1498Szrj basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)153738fd1498Szrj getline(basic_istream<_CharT, _Traits>& __in, 153838fd1498Szrj basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 153938fd1498Szrj { 154038fd1498Szrj typedef basic_istream<_CharT, _Traits> __istream_type; 154138fd1498Szrj typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 154238fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 154338fd1498Szrj typedef typename __istream_type::int_type __int_type; 154438fd1498Szrj typedef typename __string_type::size_type __size_type; 154538fd1498Szrj 154638fd1498Szrj __size_type __extracted = 0; 154738fd1498Szrj const __size_type __n = __str.max_size(); 154838fd1498Szrj typename __ios_base::iostate __err = __ios_base::goodbit; 154938fd1498Szrj typename __istream_type::sentry __cerb(__in, true); 155038fd1498Szrj if (__cerb) 155138fd1498Szrj { 155238fd1498Szrj __try 155338fd1498Szrj { 155438fd1498Szrj __str.erase(); 155538fd1498Szrj const __int_type __idelim = _Traits::to_int_type(__delim); 155638fd1498Szrj const __int_type __eof = _Traits::eof(); 155738fd1498Szrj __int_type __c = __in.rdbuf()->sgetc(); 155838fd1498Szrj 155938fd1498Szrj while (__extracted < __n 156038fd1498Szrj && !_Traits::eq_int_type(__c, __eof) 156138fd1498Szrj && !_Traits::eq_int_type(__c, __idelim)) 156238fd1498Szrj { 156338fd1498Szrj __str += _Traits::to_char_type(__c); 156438fd1498Szrj ++__extracted; 156538fd1498Szrj __c = __in.rdbuf()->snextc(); 156638fd1498Szrj } 156738fd1498Szrj 156838fd1498Szrj if (_Traits::eq_int_type(__c, __eof)) 156938fd1498Szrj __err |= __ios_base::eofbit; 157038fd1498Szrj else if (_Traits::eq_int_type(__c, __idelim)) 157138fd1498Szrj { 157238fd1498Szrj ++__extracted; 157338fd1498Szrj __in.rdbuf()->sbumpc(); 157438fd1498Szrj } 157538fd1498Szrj else 157638fd1498Szrj __err |= __ios_base::failbit; 157738fd1498Szrj } 157838fd1498Szrj __catch(__cxxabiv1::__forced_unwind&) 157938fd1498Szrj { 158038fd1498Szrj __in._M_setstate(__ios_base::badbit); 158138fd1498Szrj __throw_exception_again; 158238fd1498Szrj } 158338fd1498Szrj __catch(...) 158438fd1498Szrj { 158538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 158638fd1498Szrj // 91. Description of operator>> and getline() for string<> 158738fd1498Szrj // might cause endless loop 158838fd1498Szrj __in._M_setstate(__ios_base::badbit); 158938fd1498Szrj } 159038fd1498Szrj } 159138fd1498Szrj if (!__extracted) 159238fd1498Szrj __err |= __ios_base::failbit; 159338fd1498Szrj if (__err) 159438fd1498Szrj __in.setstate(__err); 159538fd1498Szrj return __in; 159638fd1498Szrj } 159738fd1498Szrj 159838fd1498Szrj // Inhibit implicit instantiations for required instantiations, 159938fd1498Szrj // which are defined via explicit instantiations elsewhere. 1600*58e805e6Szrj #if _GLIBCXX_EXTERN_TEMPLATE 1601*58e805e6Szrj // The explicit instantiations definitions in src/c++11/string-inst.cc 1602*58e805e6Szrj // are compiled as C++14, so the new C++17 members aren't instantiated. 1603*58e805e6Szrj // Until those definitions are compiled as C++17 suppress the declaration, 1604*58e805e6Szrj // so C++17 code will implicitly instantiate std::string and std::wstring 1605*58e805e6Szrj // as needed. 1606*58e805e6Szrj # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 160738fd1498Szrj extern template class basic_string<char>; 1608*58e805e6Szrj # elif ! _GLIBCXX_USE_CXX11_ABI 1609*58e805e6Szrj // Still need to prevent implicit instantiation of the COW empty rep, 1610*58e805e6Szrj // to ensure the definition in libstdc++.so is unique (PR 86138). 1611*58e805e6Szrj extern template basic_string<char>::size_type 1612*58e805e6Szrj basic_string<char>::_Rep::_S_empty_rep_storage[]; 1613*58e805e6Szrj # endif 1614*58e805e6Szrj 161538fd1498Szrj extern template 161638fd1498Szrj basic_istream<char>& 161738fd1498Szrj operator>>(basic_istream<char>&, string&); 161838fd1498Szrj extern template 161938fd1498Szrj basic_ostream<char>& 162038fd1498Szrj operator<<(basic_ostream<char>&, const string&); 162138fd1498Szrj extern template 162238fd1498Szrj basic_istream<char>& 162338fd1498Szrj getline(basic_istream<char>&, string&, char); 162438fd1498Szrj extern template 162538fd1498Szrj basic_istream<char>& 162638fd1498Szrj getline(basic_istream<char>&, string&); 162738fd1498Szrj 162838fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 1629*58e805e6Szrj # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 163038fd1498Szrj extern template class basic_string<wchar_t>; 1631*58e805e6Szrj # elif ! _GLIBCXX_USE_CXX11_ABI 1632*58e805e6Szrj extern template basic_string<wchar_t>::size_type 1633*58e805e6Szrj basic_string<wchar_t>::_Rep::_S_empty_rep_storage[]; 1634*58e805e6Szrj # endif 1635*58e805e6Szrj 163638fd1498Szrj extern template 163738fd1498Szrj basic_istream<wchar_t>& 163838fd1498Szrj operator>>(basic_istream<wchar_t>&, wstring&); 163938fd1498Szrj extern template 164038fd1498Szrj basic_ostream<wchar_t>& 164138fd1498Szrj operator<<(basic_ostream<wchar_t>&, const wstring&); 164238fd1498Szrj extern template 164338fd1498Szrj basic_istream<wchar_t>& 164438fd1498Szrj getline(basic_istream<wchar_t>&, wstring&, wchar_t); 164538fd1498Szrj extern template 164638fd1498Szrj basic_istream<wchar_t>& 164738fd1498Szrj getline(basic_istream<wchar_t>&, wstring&); 1648*58e805e6Szrj #endif // _GLIBCXX_USE_WCHAR_T 1649*58e805e6Szrj #endif // _GLIBCXX_EXTERN_TEMPLATE 165038fd1498Szrj 165138fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 165238fd1498Szrj } // namespace std 165338fd1498Szrj 165438fd1498Szrj #endif 1655