1169691Skan// Versatile string -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan/** @file ext/vstring.tcc 31169691Skan * This file is a GNU extension to the Standard C++ Library. 32169691Skan * This is an internal header file, included by other library headers. 33169691Skan * You should not attempt to use it directly. 34169691Skan */ 35169691Skan 36169691Skan#ifndef _VSTRING_TCC 37169691Skan#define _VSTRING_TCC 1 38169691Skan 39169691Skan#pragma GCC system_header 40169691Skan 41169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 42169691Skan 43169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 44169691Skan template <typename, typename, typename> class _Base> 45169691Skan const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 46169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; 47169691Skan 48169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 49169691Skan template <typename, typename, typename> class _Base> 50169691Skan void 51169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 52169691Skan resize(size_type __n, _CharT __c) 53169691Skan { 54169691Skan const size_type __size = this->size(); 55169691Skan if (__size < __n) 56169691Skan this->append(__n - __size, __c); 57169691Skan else if (__n < __size) 58169691Skan this->_M_erase(__n, __size - __n); 59169691Skan } 60169691Skan 61169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 62169691Skan template <typename, typename, typename> class _Base> 63169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>& 64169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 65169691Skan _M_append(const _CharT* __s, size_type __n) 66169691Skan { 67169691Skan const size_type __len = __n + this->size(); 68169691Skan 69169691Skan if (__len <= this->capacity() && !this->_M_is_shared()) 70169691Skan { 71169691Skan if (__n) 72169691Skan this->_S_copy(this->_M_data() + this->size(), __s, __n); 73169691Skan } 74169691Skan else 75169691Skan this->_M_mutate(this->size(), size_type(0), __s, __n); 76169691Skan 77169691Skan this->_M_set_length(__len); 78169691Skan return *this; 79169691Skan } 80169691Skan 81169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 82169691Skan template <typename, typename, typename> class _Base> 83169691Skan template<typename _InputIterator> 84169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>& 85169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 86169691Skan _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 87169691Skan _InputIterator __k2, std::__false_type) 88169691Skan { 89169691Skan const __versa_string __s(__k1, __k2); 90169691Skan const size_type __n1 = __i2 - __i1; 91169691Skan return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), 92169691Skan __s.size()); 93169691Skan } 94169691Skan 95169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 96169691Skan template <typename, typename, typename> class _Base> 97169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>& 98169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 99169691Skan _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 100169691Skan _CharT __c) 101169691Skan { 102169691Skan _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); 103169691Skan 104169691Skan const size_type __old_size = this->size(); 105169691Skan const size_type __new_size = __old_size + __n2 - __n1; 106169691Skan 107169691Skan if (__new_size <= this->capacity() && !this->_M_is_shared()) 108169691Skan { 109169691Skan _CharT* __p = this->_M_data() + __pos1; 110169691Skan 111169691Skan const size_type __how_much = __old_size - __pos1 - __n1; 112169691Skan if (__how_much && __n1 != __n2) 113169691Skan this->_S_move(__p + __n2, __p + __n1, __how_much); 114169691Skan } 115169691Skan else 116169691Skan this->_M_mutate(__pos1, __n1, 0, __n2); 117169691Skan 118169691Skan if (__n2) 119169691Skan this->_S_assign(this->_M_data() + __pos1, __n2, __c); 120169691Skan 121169691Skan this->_M_set_length(__new_size); 122169691Skan return *this; 123169691Skan } 124169691Skan 125169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 126169691Skan template <typename, typename, typename> class _Base> 127169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>& 128169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 129169691Skan _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 130169691Skan const size_type __len2) 131169691Skan { 132169691Skan _M_check_length(__len1, __len2, "__versa_string::_M_replace"); 133169691Skan 134169691Skan const size_type __old_size = this->size(); 135169691Skan const size_type __new_size = __old_size + __len2 - __len1; 136169691Skan 137169691Skan if (__new_size <= this->capacity() && !this->_M_is_shared()) 138169691Skan { 139169691Skan _CharT* __p = this->_M_data() + __pos; 140169691Skan 141169691Skan const size_type __how_much = __old_size - __pos - __len1; 142169691Skan if (_M_disjunct(__s)) 143169691Skan { 144169691Skan if (__how_much && __len1 != __len2) 145169691Skan this->_S_move(__p + __len2, __p + __len1, __how_much); 146169691Skan if (__len2) 147169691Skan this->_S_copy(__p, __s, __len2); 148169691Skan } 149169691Skan else 150169691Skan { 151169691Skan // Work in-place. 152169691Skan if (__len2 && __len2 <= __len1) 153169691Skan this->_S_move(__p, __s, __len2); 154169691Skan if (__how_much && __len1 != __len2) 155169691Skan this->_S_move(__p + __len2, __p + __len1, __how_much); 156169691Skan if (__len2 > __len1) 157169691Skan { 158169691Skan if (__s + __len2 <= __p + __len1) 159169691Skan this->_S_move(__p, __s, __len2); 160169691Skan else if (__s >= __p + __len1) 161169691Skan this->_S_copy(__p, __s + __len2 - __len1, __len2); 162169691Skan else 163169691Skan { 164169691Skan const size_type __nleft = (__p + __len1) - __s; 165169691Skan this->_S_move(__p, __s, __nleft); 166169691Skan this->_S_copy(__p + __nleft, __p + __len2, 167169691Skan __len2 - __nleft); 168169691Skan } 169169691Skan } 170169691Skan } 171169691Skan } 172169691Skan else 173169691Skan this->_M_mutate(__pos, __len1, __s, __len2); 174169691Skan 175169691Skan this->_M_set_length(__new_size); 176169691Skan return *this; 177169691Skan } 178169691Skan 179169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 180169691Skan template <typename, typename, typename> class _Base> 181169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> 182169691Skan operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 183169691Skan const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 184169691Skan { 185169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 186169691Skan __str.reserve(__lhs.size() + __rhs.size()); 187169691Skan __str.append(__lhs); 188169691Skan __str.append(__rhs); 189169691Skan return __str; 190169691Skan } 191169691Skan 192169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 193169691Skan template <typename, typename, typename> class _Base> 194169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> 195169691Skan operator+(const _CharT* __lhs, 196169691Skan const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 197169691Skan { 198169691Skan __glibcxx_requires_string(__lhs); 199169691Skan typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 200169691Skan typedef typename __string_type::size_type __size_type; 201169691Skan const __size_type __len = _Traits::length(__lhs); 202169691Skan __string_type __str; 203169691Skan __str.reserve(__len + __rhs.size()); 204169691Skan __str.append(__lhs, __len); 205169691Skan __str.append(__rhs); 206169691Skan return __str; 207169691Skan } 208169691Skan 209169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 210169691Skan template <typename, typename, typename> class _Base> 211169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> 212169691Skan operator+(_CharT __lhs, 213169691Skan const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 214169691Skan { 215169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 216169691Skan __str.reserve(__rhs.size() + 1); 217169691Skan __str.push_back(__lhs); 218169691Skan __str.append(__rhs); 219169691Skan return __str; 220169691Skan } 221169691Skan 222169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 223169691Skan template <typename, typename, typename> class _Base> 224169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> 225169691Skan operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 226169691Skan const _CharT* __rhs) 227169691Skan { 228169691Skan __glibcxx_requires_string(__rhs); 229169691Skan typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 230169691Skan typedef typename __string_type::size_type __size_type; 231169691Skan const __size_type __len = _Traits::length(__rhs); 232169691Skan __string_type __str; 233169691Skan __str.reserve(__lhs.size() + __len); 234169691Skan __str.append(__lhs); 235169691Skan __str.append(__rhs, __len); 236169691Skan return __str; 237169691Skan } 238169691Skan 239169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 240169691Skan template <typename, typename, typename> class _Base> 241169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> 242169691Skan operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 243169691Skan _CharT __rhs) 244169691Skan { 245169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 246169691Skan __str.reserve(__lhs.size() + 1); 247169691Skan __str.append(__lhs); 248169691Skan __str.push_back(__rhs); 249169691Skan return __str; 250169691Skan } 251169691Skan 252169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 253169691Skan template <typename, typename, typename> class _Base> 254169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 255169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 256169691Skan copy(_CharT* __s, size_type __n, size_type __pos) const 257169691Skan { 258169691Skan _M_check(__pos, "__versa_string::copy"); 259169691Skan __n = _M_limit(__pos, __n); 260169691Skan __glibcxx_requires_string_len(__s, __n); 261169691Skan if (__n) 262169691Skan this->_S_copy(__s, this->_M_data() + __pos, __n); 263169691Skan // 21.3.5.7 par 3: do not append null. (good.) 264169691Skan return __n; 265169691Skan } 266169691Skan 267169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 268169691Skan template <typename, typename, typename> class _Base> 269169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 270169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 271169691Skan find(const _CharT* __s, size_type __pos, size_type __n) const 272169691Skan { 273169691Skan __glibcxx_requires_string_len(__s, __n); 274169691Skan const size_type __size = this->size(); 275169691Skan const _CharT* __data = this->_M_data(); 276169691Skan 277169691Skan if (__n == 0) 278169691Skan return __pos <= __size ? __pos : npos; 279169691Skan 280169691Skan if (__n <= __size) 281169691Skan { 282169691Skan for (; __pos <= __size - __n; ++__pos) 283169691Skan if (traits_type::eq(__data[__pos], __s[0]) 284169691Skan && traits_type::compare(__data + __pos + 1, 285169691Skan __s + 1, __n - 1) == 0) 286169691Skan return __pos; 287169691Skan } 288169691Skan return npos; 289169691Skan } 290169691Skan 291169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 292169691Skan template <typename, typename, typename> class _Base> 293169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 294169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 295169691Skan find(_CharT __c, size_type __pos) const 296169691Skan { 297169691Skan size_type __ret = npos; 298169691Skan const size_type __size = this->size(); 299169691Skan if (__pos < __size) 300169691Skan { 301169691Skan const _CharT* __data = this->_M_data(); 302169691Skan const size_type __n = __size - __pos; 303169691Skan const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 304169691Skan if (__p) 305169691Skan __ret = __p - __data; 306169691Skan } 307169691Skan return __ret; 308169691Skan } 309169691Skan 310169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 311169691Skan template <typename, typename, typename> class _Base> 312169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 313169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 314169691Skan rfind(const _CharT* __s, size_type __pos, size_type __n) const 315169691Skan { 316169691Skan __glibcxx_requires_string_len(__s, __n); 317169691Skan const size_type __size = this->size(); 318169691Skan if (__n <= __size) 319169691Skan { 320169691Skan __pos = std::min(size_type(__size - __n), __pos); 321169691Skan const _CharT* __data = this->_M_data(); 322169691Skan do 323169691Skan { 324169691Skan if (traits_type::compare(__data + __pos, __s, __n) == 0) 325169691Skan return __pos; 326169691Skan } 327169691Skan while (__pos-- > 0); 328169691Skan } 329169691Skan return npos; 330169691Skan } 331169691Skan 332169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 333169691Skan template <typename, typename, typename> class _Base> 334169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 335169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 336169691Skan rfind(_CharT __c, size_type __pos) const 337169691Skan { 338169691Skan size_type __size = this->size(); 339169691Skan if (__size) 340169691Skan { 341169691Skan if (--__size > __pos) 342169691Skan __size = __pos; 343169691Skan for (++__size; __size-- > 0; ) 344169691Skan if (traits_type::eq(this->_M_data()[__size], __c)) 345169691Skan return __size; 346169691Skan } 347169691Skan return npos; 348169691Skan } 349169691Skan 350169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 351169691Skan template <typename, typename, typename> class _Base> 352169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 353169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 354169691Skan find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 355169691Skan { 356169691Skan __glibcxx_requires_string_len(__s, __n); 357169691Skan for (; __n && __pos < this->size(); ++__pos) 358169691Skan { 359169691Skan const _CharT* __p = traits_type::find(__s, __n, 360169691Skan this->_M_data()[__pos]); 361169691Skan if (__p) 362169691Skan return __pos; 363169691Skan } 364169691Skan return npos; 365169691Skan } 366169691Skan 367169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 368169691Skan template <typename, typename, typename> class _Base> 369169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 370169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 371169691Skan find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 372169691Skan { 373169691Skan __glibcxx_requires_string_len(__s, __n); 374169691Skan size_type __size = this->size(); 375169691Skan if (__size && __n) 376169691Skan { 377169691Skan if (--__size > __pos) 378169691Skan __size = __pos; 379169691Skan do 380169691Skan { 381169691Skan if (traits_type::find(__s, __n, this->_M_data()[__size])) 382169691Skan return __size; 383169691Skan } 384169691Skan while (__size-- != 0); 385169691Skan } 386169691Skan return npos; 387169691Skan } 388169691Skan 389169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 390169691Skan template <typename, typename, typename> class _Base> 391169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 392169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 393169691Skan find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 394169691Skan { 395169691Skan __glibcxx_requires_string_len(__s, __n); 396169691Skan for (; __pos < this->size(); ++__pos) 397169691Skan if (!traits_type::find(__s, __n, this->_M_data()[__pos])) 398169691Skan return __pos; 399169691Skan return npos; 400169691Skan } 401169691Skan 402169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 403169691Skan template <typename, typename, typename> class _Base> 404169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 405169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 406169691Skan find_first_not_of(_CharT __c, size_type __pos) const 407169691Skan { 408169691Skan for (; __pos < this->size(); ++__pos) 409169691Skan if (!traits_type::eq(this->_M_data()[__pos], __c)) 410169691Skan return __pos; 411169691Skan return npos; 412169691Skan } 413169691Skan 414169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 415169691Skan template <typename, typename, typename> class _Base> 416169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 417169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 418169691Skan find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 419169691Skan { 420169691Skan __glibcxx_requires_string_len(__s, __n); 421169691Skan size_type __size = this->size(); 422169691Skan if (__size) 423169691Skan { 424169691Skan if (--__size > __pos) 425169691Skan __size = __pos; 426169691Skan do 427169691Skan { 428169691Skan if (!traits_type::find(__s, __n, this->_M_data()[__size])) 429169691Skan return __size; 430169691Skan } 431169691Skan while (__size--); 432169691Skan } 433169691Skan return npos; 434169691Skan } 435169691Skan 436169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 437169691Skan template <typename, typename, typename> class _Base> 438169691Skan typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 439169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 440169691Skan find_last_not_of(_CharT __c, size_type __pos) const 441169691Skan { 442169691Skan size_type __size = this->size(); 443169691Skan if (__size) 444169691Skan { 445169691Skan if (--__size > __pos) 446169691Skan __size = __pos; 447169691Skan do 448169691Skan { 449169691Skan if (!traits_type::eq(this->_M_data()[__size], __c)) 450169691Skan return __size; 451169691Skan } 452169691Skan while (__size--); 453169691Skan } 454169691Skan return npos; 455169691Skan } 456169691Skan 457169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 458169691Skan template <typename, typename, typename> class _Base> 459169691Skan int 460169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 461169691Skan compare(size_type __pos, size_type __n, const __versa_string& __str) const 462169691Skan { 463169691Skan _M_check(__pos, "__versa_string::compare"); 464169691Skan __n = _M_limit(__pos, __n); 465169691Skan const size_type __osize = __str.size(); 466169691Skan const size_type __len = std::min(__n, __osize); 467169691Skan int __r = traits_type::compare(this->_M_data() + __pos, 468169691Skan __str.data(), __len); 469169691Skan if (!__r) 470169691Skan __r = __n - __osize; 471169691Skan return __r; 472169691Skan } 473169691Skan 474169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 475169691Skan template <typename, typename, typename> class _Base> 476169691Skan int 477169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 478169691Skan compare(size_type __pos1, size_type __n1, const __versa_string& __str, 479169691Skan size_type __pos2, size_type __n2) const 480169691Skan { 481169691Skan _M_check(__pos1, "__versa_string::compare"); 482169691Skan __str._M_check(__pos2, "__versa_string::compare"); 483169691Skan __n1 = _M_limit(__pos1, __n1); 484169691Skan __n2 = __str._M_limit(__pos2, __n2); 485169691Skan const size_type __len = std::min(__n1, __n2); 486169691Skan int __r = traits_type::compare(this->_M_data() + __pos1, 487169691Skan __str.data() + __pos2, __len); 488169691Skan if (!__r) 489169691Skan __r = __n1 - __n2; 490169691Skan return __r; 491169691Skan } 492169691Skan 493169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 494169691Skan template <typename, typename, typename> class _Base> 495169691Skan int 496169691Skan __versa_string<_CharT, _Traits, _Alloc, _Base>:: 497169691Skan compare(const _CharT* __s) const 498169691Skan { 499169691Skan __glibcxx_requires_string(__s); 500169691Skan const size_type __size = this->size(); 501169691Skan const size_type __osize = traits_type::length(__s); 502169691Skan const size_type __len = std::min(__size, __osize); 503169691Skan int __r = traits_type::compare(this->_M_data(), __s, __len); 504169691Skan if (!__r) 505169691Skan __r = __size - __osize; 506169691Skan return __r; 507169691Skan } 508169691Skan 509169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 510169691Skan template <typename, typename, typename> class _Base> 511169691Skan int 512169691Skan __versa_string <_CharT, _Traits, _Alloc, _Base>:: 513169691Skan compare(size_type __pos, size_type __n1, const _CharT* __s) const 514169691Skan { 515169691Skan __glibcxx_requires_string(__s); 516169691Skan _M_check(__pos, "__versa_string::compare"); 517169691Skan __n1 = _M_limit(__pos, __n1); 518169691Skan const size_type __osize = traits_type::length(__s); 519169691Skan const size_type __len = std::min(__n1, __osize); 520169691Skan int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 521169691Skan if (!__r) 522169691Skan __r = __n1 - __osize; 523169691Skan return __r; 524169691Skan } 525169691Skan 526169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 527169691Skan template <typename, typename, typename> class _Base> 528169691Skan int 529169691Skan __versa_string <_CharT, _Traits, _Alloc, _Base>:: 530169691Skan compare(size_type __pos, size_type __n1, const _CharT* __s, 531169691Skan size_type __n2) const 532169691Skan { 533169691Skan __glibcxx_requires_string_len(__s, __n2); 534169691Skan _M_check(__pos, "__versa_string::compare"); 535169691Skan __n1 = _M_limit(__pos, __n1); 536169691Skan const size_type __len = std::min(__n1, __n2); 537169691Skan int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 538169691Skan if (!__r) 539169691Skan __r = __n1 - __n2; 540169691Skan return __r; 541169691Skan } 542169691Skan 543169691Skan_GLIBCXX_END_NAMESPACE 544169691Skan 545169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 546169691Skan 547169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 548169691Skan template <typename, typename, typename> class _Base> 549169691Skan basic_istream<_CharT, _Traits>& 550169691Skan operator>>(basic_istream<_CharT, _Traits>& __in, 551169691Skan __gnu_cxx::__versa_string<_CharT, _Traits, 552169691Skan _Alloc, _Base>& __str) 553169691Skan { 554169691Skan typedef basic_istream<_CharT, _Traits> __istream_type; 555169691Skan typedef typename __istream_type::int_type __int_type; 556169691Skan typedef typename __istream_type::__streambuf_type __streambuf_type; 557169691Skan typedef typename __istream_type::__ctype_type __ctype_type; 558169691Skan typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 559169691Skan __string_type; 560169691Skan typedef typename __string_type::size_type __size_type; 561169691Skan 562169691Skan __size_type __extracted = 0; 563169691Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 564169691Skan typename __istream_type::sentry __cerb(__in, false); 565169691Skan if (__cerb) 566169691Skan { 567169691Skan try 568169691Skan { 569169691Skan // Avoid reallocation for common case. 570169691Skan __str.erase(); 571169691Skan _CharT __buf[128]; 572169691Skan __size_type __len = 0; 573169691Skan const streamsize __w = __in.width(); 574169691Skan const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 575169691Skan : __str.max_size(); 576169691Skan const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 577169691Skan const __int_type __eof = _Traits::eof(); 578169691Skan __streambuf_type* __sb = __in.rdbuf(); 579169691Skan __int_type __c = __sb->sgetc(); 580169691Skan 581169691Skan while (__extracted < __n 582169691Skan && !_Traits::eq_int_type(__c, __eof) 583169691Skan && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) 584169691Skan { 585169691Skan if (__len == sizeof(__buf) / sizeof(_CharT)) 586169691Skan { 587169691Skan __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 588169691Skan __len = 0; 589169691Skan } 590169691Skan __buf[__len++] = _Traits::to_char_type(__c); 591169691Skan ++__extracted; 592169691Skan __c = __sb->snextc(); 593169691Skan } 594169691Skan __str.append(__buf, __len); 595169691Skan 596169691Skan if (_Traits::eq_int_type(__c, __eof)) 597169691Skan __err |= ios_base::eofbit; 598169691Skan __in.width(0); 599169691Skan } 600169691Skan catch(...) 601169691Skan { 602169691Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 603169691Skan // 91. Description of operator>> and getline() for string<> 604169691Skan // might cause endless loop 605169691Skan __in._M_setstate(ios_base::badbit); 606169691Skan } 607169691Skan } 608169691Skan // 211. operator>>(istream&, string&) doesn't set failbit 609169691Skan if (!__extracted) 610169691Skan __err |= ios_base::failbit; 611169691Skan if (__err) 612169691Skan __in.setstate(__err); 613169691Skan return __in; 614169691Skan } 615169691Skan 616169691Skan template<typename _CharT, typename _Traits, typename _Alloc, 617169691Skan template <typename, typename, typename> class _Base> 618169691Skan basic_istream<_CharT, _Traits>& 619169691Skan getline(basic_istream<_CharT, _Traits>& __in, 620169691Skan __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, 621169691Skan _CharT __delim) 622169691Skan { 623169691Skan typedef basic_istream<_CharT, _Traits> __istream_type; 624169691Skan typedef typename __istream_type::int_type __int_type; 625169691Skan typedef typename __istream_type::__streambuf_type __streambuf_type; 626169691Skan typedef typename __istream_type::__ctype_type __ctype_type; 627169691Skan typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 628169691Skan __string_type; 629169691Skan typedef typename __string_type::size_type __size_type; 630169691Skan 631169691Skan __size_type __extracted = 0; 632169691Skan const __size_type __n = __str.max_size(); 633169691Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 634169691Skan typename __istream_type::sentry __cerb(__in, true); 635169691Skan if (__cerb) 636169691Skan { 637169691Skan try 638169691Skan { 639169691Skan // Avoid reallocation for common case. 640169691Skan __str.erase(); 641169691Skan _CharT __buf[128]; 642169691Skan __size_type __len = 0; 643169691Skan const __int_type __idelim = _Traits::to_int_type(__delim); 644169691Skan const __int_type __eof = _Traits::eof(); 645169691Skan __streambuf_type* __sb = __in.rdbuf(); 646169691Skan __int_type __c = __sb->sgetc(); 647169691Skan 648169691Skan while (__extracted < __n 649169691Skan && !_Traits::eq_int_type(__c, __eof) 650169691Skan && !_Traits::eq_int_type(__c, __idelim)) 651169691Skan { 652169691Skan if (__len == sizeof(__buf) / sizeof(_CharT)) 653169691Skan { 654169691Skan __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 655169691Skan __len = 0; 656169691Skan } 657169691Skan __buf[__len++] = _Traits::to_char_type(__c); 658169691Skan ++__extracted; 659169691Skan __c = __sb->snextc(); 660169691Skan } 661169691Skan __str.append(__buf, __len); 662169691Skan 663169691Skan if (_Traits::eq_int_type(__c, __eof)) 664169691Skan __err |= ios_base::eofbit; 665169691Skan else if (_Traits::eq_int_type(__c, __idelim)) 666169691Skan { 667169691Skan ++__extracted; 668169691Skan __sb->sbumpc(); 669169691Skan } 670169691Skan else 671169691Skan __err |= ios_base::failbit; 672169691Skan } 673169691Skan catch(...) 674169691Skan { 675169691Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 676169691Skan // 91. Description of operator>> and getline() for string<> 677169691Skan // might cause endless loop 678169691Skan __in._M_setstate(ios_base::badbit); 679169691Skan } 680169691Skan } 681169691Skan if (!__extracted) 682169691Skan __err |= ios_base::failbit; 683169691Skan if (__err) 684169691Skan __in.setstate(__err); 685169691Skan return __in; 686169691Skan } 687169691Skan 688169691Skan_GLIBCXX_END_NAMESPACE 689169691Skan 690169691Skan#endif // _VSTRING_TCC 691