LCOV - code coverage report
Current view: top level - /usr/include/c++/14/bits - basic_string.tcc (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 0.0 % 12 0
Test Date: 2026-02-27 05:14:50 Functions: 0.0 % 3 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Components for manipulating sequences of characters -*- C++ -*-
       2              : 
       3              : // Copyright (C) 1997-2024 Free Software Foundation, Inc.
       4              : //
       5              : // This file is part of the GNU ISO C++ Library.  This library is free
       6              : // software; you can redistribute it and/or modify it under the
       7              : // terms of the GNU General Public License as published by the
       8              : // Free Software Foundation; either version 3, or (at your option)
       9              : // any later version.
      10              : 
      11              : // This library is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : 
      16              : // Under Section 7 of GPL version 3, you are granted additional
      17              : // permissions described in the GCC Runtime Library Exception, version
      18              : // 3.1, as published by the Free Software Foundation.
      19              : 
      20              : // You should have received a copy of the GNU General Public License and
      21              : // a copy of the GCC Runtime Library Exception along with this program;
      22              : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23              : // <http://www.gnu.org/licenses/>.
      24              : 
      25              : /** @file bits/basic_string.tcc
      26              :  *  This is an internal header file, included by other library headers.
      27              :  *  Do not attempt to use it directly. @headername{string}
      28              :  */
      29              : 
      30              : //
      31              : // ISO C++ 14882: 21  Strings library
      32              : //
      33              : 
      34              : // Written by Jason Merrill based upon the specification by Takanori Adachi
      35              : // in ANSI X3J16/94-0013R2.  Rewritten by Nathan Myers to ISO-14882.
      36              : // Non-reference-counted implementation written by Paolo Carlini and
      37              : // updated by Jonathan Wakely for ISO-14882-2011.
      38              : 
      39              : #ifndef _BASIC_STRING_TCC
      40              : #define _BASIC_STRING_TCC 1
      41              : 
      42              : #pragma GCC system_header
      43              : 
      44              : #include <bits/cxxabi_forced.h>
      45              : 
      46              : namespace std _GLIBCXX_VISIBILITY(default)
      47              : {
      48              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      49              : 
      50              : #if _GLIBCXX_USE_CXX11_ABI
      51              : 
      52              :   template<typename _CharT, typename _Traits, typename _Alloc>
      53              :     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
      54              :     basic_string<_CharT, _Traits, _Alloc>::npos;
      55              : 
      56              :   template<typename _CharT, typename _Traits, typename _Alloc>
      57              :     _GLIBCXX20_CONSTEXPR
      58              :     void
      59              :     basic_string<_CharT, _Traits, _Alloc>::
      60              :     swap(basic_string& __s) _GLIBCXX_NOEXCEPT
      61              :     {
      62              :       if (this == std::__addressof(__s))
      63              :     return;
      64              : 
      65              :       _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator());
      66              : 
      67              :       if (_M_is_local())
      68              :     if (__s._M_is_local())
      69              :       {
      70              :         if (length() && __s.length())
      71              :           {
      72              :         _CharT __tmp_data[_S_local_capacity + 1];
      73              :         traits_type::copy(__tmp_data, __s._M_local_buf,
      74              :                   __s.length() + 1);
      75              :         traits_type::copy(__s._M_local_buf, _M_local_buf,
      76              :                   length() + 1);
      77              :         traits_type::copy(_M_local_buf, __tmp_data,
      78              :                   __s.length() + 1);
      79              :           }
      80              :         else if (__s.length())
      81              :           {
      82              :         _M_init_local_buf();
      83              :         traits_type::copy(_M_local_buf, __s._M_local_buf,
      84              :                   __s.length() + 1);
      85              :         _M_length(__s.length());
      86              :         __s._M_set_length(0);
      87              :         return;
      88              :           }
      89              :         else if (length())
      90              :           {
      91              :         __s._M_init_local_buf();
      92              :         traits_type::copy(__s._M_local_buf, _M_local_buf,
      93              :                   length() + 1);
      94              :         __s._M_length(length());
      95              :         _M_set_length(0);
      96              :         return;
      97              :           }
      98              :       }
      99              :     else
     100              :       {
     101              :         const size_type __tmp_capacity = __s._M_allocated_capacity;
     102              :         __s._M_init_local_buf();
     103              :         traits_type::copy(__s._M_local_buf, _M_local_buf,
     104              :                   length() + 1);
     105              :         _M_data(__s._M_data());
     106              :         __s._M_data(__s._M_local_buf);
     107              :         _M_capacity(__tmp_capacity);
     108              :       }
     109              :       else
     110              :     {
     111              :       const size_type __tmp_capacity = _M_allocated_capacity;
     112              :       if (__s._M_is_local())
     113              :         {
     114              :           _M_init_local_buf();
     115              :           traits_type::copy(_M_local_buf, __s._M_local_buf,
     116              :                 __s.length() + 1);
     117              :           __s._M_data(_M_data());
     118              :           _M_data(_M_local_buf);
     119              :         }
     120              :       else
     121              :         {
     122              :           pointer __tmp_ptr = _M_data();
     123              :           _M_data(__s._M_data());
     124              :           __s._M_data(__tmp_ptr);
     125              :           _M_capacity(__s._M_allocated_capacity);
     126              :         }
     127              :       __s._M_capacity(__tmp_capacity);
     128              :     }
     129              : 
     130              :       const size_type __tmp_length = length();
     131              :       _M_length(__s.length());
     132              :       __s._M_length(__tmp_length);
     133              :     }
     134              : 
     135              :   template<typename _CharT, typename _Traits, typename _Alloc>
     136              :     _GLIBCXX20_CONSTEXPR
     137              :     typename basic_string<_CharT, _Traits, _Alloc>::pointer
     138              :     basic_string<_CharT, _Traits, _Alloc>::
     139              :     _M_create(size_type& __capacity, size_type __old_capacity)
     140              :     {
     141              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     142              :       // 83.  String::npos vs. string::max_size()
     143              :       if (__capacity > max_size())
     144              :     std::__throw_length_error(__N("basic_string::_M_create"));
     145              : 
     146              :       // The below implements an exponential growth policy, necessary to
     147              :       // meet amortized linear time requirements of the library: see
     148              :       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
     149              :       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
     150              :     {
     151              :       __capacity = 2 * __old_capacity;
     152              :       // Never allocate a string bigger than max_size.
     153              :       if (__capacity > max_size())
     154              :         __capacity = max_size();
     155              :     }
     156              : 
     157              :       // NB: Need an array of char_type[__capacity], plus a terminating
     158              :       // null char_type() element.
     159              :       return _S_allocate(_M_get_allocator(), __capacity + 1);
     160              :     }
     161              : 
     162              :   // NB: This is the special case for Input Iterators, used in
     163              :   // istreambuf_iterators, etc.
     164              :   // Input Iterators have a cost structure very different from
     165              :   // pointers, calling for a different coding style.
     166              :   template<typename _CharT, typename _Traits, typename _Alloc>
     167              :     template<typename _InIterator>
     168              :       _GLIBCXX20_CONSTEXPR
     169              :       void
     170              :       basic_string<_CharT, _Traits, _Alloc>::
     171              :       _M_construct(_InIterator __beg, _InIterator __end,
     172              :            std::input_iterator_tag)
     173              :       {
     174              :     size_type __len = 0;
     175              :     size_type __capacity = size_type(_S_local_capacity);
     176              : 
     177              :     _M_init_local_buf();
     178              : 
     179              :     while (__beg != __end && __len < __capacity)
     180              :       {
     181              :         _M_local_buf[__len++] = *__beg;
     182              :         ++__beg;
     183              :       }
     184              : 
     185              :     struct _Guard
     186              :     {
     187              :       _GLIBCXX20_CONSTEXPR
     188              :       explicit _Guard(basic_string* __s) : _M_guarded(__s) { }
     189              : 
     190              :       _GLIBCXX20_CONSTEXPR
     191              :       ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); }
     192              : 
     193              :       basic_string* _M_guarded;
     194              :     } __guard(this);
     195              : 
     196              :     while (__beg != __end)
     197              :       {
     198              :         if (__len == __capacity)
     199              :           {
     200              :         // Allocate more space.
     201              :         __capacity = __len + 1;
     202              :         pointer __another = _M_create(__capacity, __len);
     203              :         this->_S_copy(__another, _M_data(), __len);
     204              :         _M_dispose();
     205              :         _M_data(__another);
     206              :         _M_capacity(__capacity);
     207              :           }
     208              :         traits_type::assign(_M_data()[__len++], *__beg);
     209              :         ++__beg;
     210              :       }
     211              : 
     212              :     __guard._M_guarded = 0;
     213              : 
     214              :     _M_set_length(__len);
     215              :       }
     216              : 
     217              :   template<typename _CharT, typename _Traits, typename _Alloc>
     218              :     template<typename _InIterator>
     219              :       _GLIBCXX20_CONSTEXPR
     220              :       void
     221            0 :       basic_string<_CharT, _Traits, _Alloc>::
     222              :       _M_construct(_InIterator __beg, _InIterator __end,
     223              :            std::forward_iterator_tag)
     224              :       {
     225            0 :     size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
     226              : 
     227            0 :     if (__dnew > size_type(_S_local_capacity))
     228              :       {
     229            0 :         _M_data(_M_create(__dnew, size_type(0)));
     230            0 :         _M_capacity(__dnew);
     231              :       }
     232              :     else
     233              :       _M_init_local_buf();
     234              : 
     235              :     // Check for out_of_range and length_error exceptions.
     236              :     struct _Guard
     237              :     {
     238              :       _GLIBCXX20_CONSTEXPR
     239            0 :       explicit _Guard(basic_string* __s) : _M_guarded(__s) { }
     240              : 
     241              :       _GLIBCXX20_CONSTEXPR
     242            0 :       ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); }
     243              : 
     244              :       basic_string* _M_guarded;
     245            0 :     } __guard(this);
     246              : 
     247            0 :     this->_S_copy_chars(_M_data(), __beg, __end);
     248              : 
     249            0 :     __guard._M_guarded = 0;
     250              : 
     251            0 :     _M_set_length(__dnew);
     252            0 :       }
     253              : 
     254              :   template<typename _CharT, typename _Traits, typename _Alloc>
     255              :     _GLIBCXX20_CONSTEXPR
     256              :     void
     257              :     basic_string<_CharT, _Traits, _Alloc>::
     258              :     _M_construct(size_type __n, _CharT __c)
     259              :     {
     260              :       if (__n > size_type(_S_local_capacity))
     261              :     {
     262              :       _M_data(_M_create(__n, size_type(0)));
     263              :       _M_capacity(__n);
     264              :     }
     265              :       else
     266              :     _M_init_local_buf();
     267              : 
     268              :       if (__n)
     269              :     this->_S_assign(_M_data(), __n, __c);
     270              : 
     271              :       _M_set_length(__n);
     272              :     }
     273              : 
     274              :   template<typename _CharT, typename _Traits, typename _Alloc>
     275              :     _GLIBCXX20_CONSTEXPR
     276              :     void
     277              :     basic_string<_CharT, _Traits, _Alloc>::
     278              :     _M_assign(const basic_string& __str)
     279              :     {
     280              :       if (this != std::__addressof(__str))
     281              :     {
     282              :       const size_type __rsize = __str.length();
     283              :       const size_type __capacity = capacity();
     284              : 
     285              :       if (__rsize > __capacity)
     286              :         {
     287              :           size_type __new_capacity = __rsize;
     288              :           pointer __tmp = _M_create(__new_capacity, __capacity);
     289              :           _M_dispose();
     290              :           _M_data(__tmp);
     291              :           _M_capacity(__new_capacity);
     292              :         }
     293              : 
     294              :       if (__rsize)
     295              :         this->_S_copy(_M_data(), __str._M_data(), __rsize);
     296              : 
     297              :       _M_set_length(__rsize);
     298              :     }
     299              :     }
     300              : 
     301              :   template<typename _CharT, typename _Traits, typename _Alloc>
     302              :     _GLIBCXX20_CONSTEXPR
     303              :     void
     304              :     basic_string<_CharT, _Traits, _Alloc>::
     305              :     reserve(size_type __res)
     306              :     {
     307              :       const size_type __capacity = capacity();
     308              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     309              :       // 2968. Inconsistencies between basic_string reserve and
     310              :       // vector/unordered_map/unordered_set reserve functions
     311              :       // P0966 reserve should not shrink
     312              :       if (__res <= __capacity)
     313              :     return;
     314              : 
     315              :       pointer __tmp = _M_create(__res, __capacity);
     316              :       this->_S_copy(__tmp, _M_data(), length() + 1);
     317              :       _M_dispose();
     318              :       _M_data(__tmp);
     319              :       _M_capacity(__res);
     320              :     }
     321              : 
     322              :   template<typename _CharT, typename _Traits, typename _Alloc>
     323              :     _GLIBCXX20_CONSTEXPR
     324              :     void
     325              :     basic_string<_CharT, _Traits, _Alloc>::
     326              :     _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
     327              :           size_type __len2)
     328              :     {
     329              :       const size_type __how_much = length() - __pos - __len1;
     330              : 
     331              :       size_type __new_capacity = length() + __len2 - __len1;
     332              :       pointer __r = _M_create(__new_capacity, capacity());
     333              : 
     334              :       if (__pos)
     335              :     this->_S_copy(__r, _M_data(), __pos);
     336              :       if (__s && __len2)
     337              :     this->_S_copy(__r + __pos, __s, __len2);
     338              :       if (__how_much)
     339              :     this->_S_copy(__r + __pos + __len2,
     340              :               _M_data() + __pos + __len1, __how_much);
     341              : 
     342              :       _M_dispose();
     343              :       _M_data(__r);
     344              :       _M_capacity(__new_capacity);
     345              :     }
     346              : 
     347              :   template<typename _CharT, typename _Traits, typename _Alloc>
     348              :     _GLIBCXX20_CONSTEXPR
     349              :     void
     350              :     basic_string<_CharT, _Traits, _Alloc>::
     351              :     _M_erase(size_type __pos, size_type __n)
     352              :     {
     353              :       const size_type __how_much = length() - __pos - __n;
     354              : 
     355              :       if (__how_much && __n)
     356              :     this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much);
     357              : 
     358              :       _M_set_length(length() - __n);
     359              :     }
     360              : 
     361              :   template<typename _CharT, typename _Traits, typename _Alloc>
     362              :     _GLIBCXX20_CONSTEXPR
     363              :     void
     364              :     basic_string<_CharT, _Traits, _Alloc>::
     365              :     reserve()
     366              :     {
     367              :       if (_M_is_local())
     368              :     return;
     369              : 
     370              :       const size_type __length = length();
     371              :       const size_type __capacity = _M_allocated_capacity;
     372              : 
     373              :       if (__length <= size_type(_S_local_capacity))
     374              :     {
     375              :       _M_init_local_buf();
     376              :       this->_S_copy(_M_local_buf, _M_data(), __length + 1);
     377              :       _M_destroy(__capacity);
     378              :       _M_data(_M_local_data());
     379              :     }
     380              : #if __cpp_exceptions
     381              :       else if (__length < __capacity)
     382              :     try
     383              :       {
     384              :         pointer __tmp = _S_allocate(_M_get_allocator(), __length + 1);
     385              :         this->_S_copy(__tmp, _M_data(), __length + 1);
     386              :         _M_dispose();
     387              :         _M_data(__tmp);
     388              :         _M_capacity(__length);
     389              :       }
     390              :     catch (const __cxxabiv1::__forced_unwind&)
     391              :       { throw; }
     392              :     catch (...)
     393              :       { /* swallow the exception */ }
     394              : #endif
     395              :     }
     396              : 
     397              :   template<typename _CharT, typename _Traits, typename _Alloc>
     398              :     _GLIBCXX20_CONSTEXPR
     399              :     void
     400              :     basic_string<_CharT, _Traits, _Alloc>::
     401              :     resize(size_type __n, _CharT __c)
     402              :     {
     403              :       const size_type __size = this->size();
     404              :       if (__size < __n)
     405              :     this->append(__n - __size, __c);
     406              :       else if (__n < __size)
     407              :     this->_M_set_length(__n);
     408              :     }
     409              : 
     410              :   template<typename _CharT, typename _Traits, typename _Alloc>
     411              :     _GLIBCXX20_CONSTEXPR
     412              :     basic_string<_CharT, _Traits, _Alloc>&
     413              :     basic_string<_CharT, _Traits, _Alloc>::
     414              :     _M_append(const _CharT* __s, size_type __n)
     415              :     {
     416              :       const size_type __len = __n + this->size();
     417              : 
     418              :       if (__len <= this->capacity())
     419              :     {
     420              :       if (__n)
     421              :         this->_S_copy(this->_M_data() + this->size(), __s, __n);
     422              :     }
     423              :       else
     424              :     this->_M_mutate(this->size(), size_type(0), __s, __n);
     425              : 
     426              :       this->_M_set_length(__len);
     427              :       return *this;
     428              :     }
     429              : 
     430              :   template<typename _CharT, typename _Traits, typename _Alloc>
     431              :     template<typename _InputIterator>
     432              :       _GLIBCXX20_CONSTEXPR
     433              :       basic_string<_CharT, _Traits, _Alloc>&
     434              :       basic_string<_CharT, _Traits, _Alloc>::
     435              :       _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
     436              :               _InputIterator __k1, _InputIterator __k2,
     437              :               std::__false_type)
     438              :       {
     439              :     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     440              :     // 2788. unintentionally require a default constructible allocator
     441              :     const basic_string __s(__k1, __k2, this->get_allocator());
     442              :     const size_type __n1 = __i2 - __i1;
     443              :     return _M_replace(__i1 - begin(), __n1, __s._M_data(),
     444              :               __s.size());
     445              :       }
     446              : 
     447              :   template<typename _CharT, typename _Traits, typename _Alloc>
     448              :     _GLIBCXX20_CONSTEXPR
     449              :     basic_string<_CharT, _Traits, _Alloc>&
     450              :     basic_string<_CharT, _Traits, _Alloc>::
     451              :     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
     452              :            _CharT __c)
     453              :     {
     454              :       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
     455              : 
     456              :       const size_type __old_size = this->size();
     457              :       const size_type __new_size = __old_size + __n2 - __n1;
     458              : 
     459              :       if (__new_size <= this->capacity())
     460              :     {
     461              :       pointer __p = this->_M_data() + __pos1;
     462              : 
     463              :       const size_type __how_much = __old_size - __pos1 - __n1;
     464              :       if (__how_much && __n1 != __n2)
     465              :         this->_S_move(__p + __n2, __p + __n1, __how_much);
     466              :     }
     467              :       else
     468              :     this->_M_mutate(__pos1, __n1, 0, __n2);
     469              : 
     470              :       if (__n2)
     471              :     this->_S_assign(this->_M_data() + __pos1, __n2, __c);
     472              : 
     473              :       this->_M_set_length(__new_size);
     474              :       return *this;
     475              :     }
     476              : 
     477              :   template<typename _CharT, typename _Traits, typename _Alloc>
     478              :     __attribute__((__noinline__, __noclone__, __cold__)) void
     479              :     basic_string<_CharT, _Traits, _Alloc>::
     480              :     _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s,
     481              :             const size_type __len2, const size_type __how_much)
     482              :     {
     483              :       // Work in-place.
     484              :       if (__len2 && __len2 <= __len1)
     485              :     this->_S_move(__p, __s, __len2);
     486              :       if (__how_much && __len1 != __len2)
     487              :     this->_S_move(__p + __len2, __p + __len1, __how_much);
     488              :       if (__len2 > __len1)
     489              :     {
     490              :       if (__s + __len2 <= __p + __len1)
     491              :         this->_S_move(__p, __s, __len2);
     492              :       else if (__s >= __p + __len1)
     493              :         {
     494              :           // Hint to middle end that __p and __s overlap
     495              :           // (PR 98465).
     496              :           const size_type __poff = (__s - __p) + (__len2 - __len1);
     497              :           this->_S_copy(__p, __p + __poff, __len2);
     498              :         }
     499              :       else
     500              :         {
     501              :           const size_type __nleft = (__p + __len1) - __s;
     502              :           this->_S_move(__p, __s, __nleft);
     503              :           this->_S_copy(__p + __nleft, __p + __len2, __len2 - __nleft);
     504              :         }
     505              :     }
     506              :     }
     507              : 
     508              :   template<typename _CharT, typename _Traits, typename _Alloc>
     509              :     _GLIBCXX20_CONSTEXPR
     510              :     basic_string<_CharT, _Traits, _Alloc>&
     511              :     basic_string<_CharT, _Traits, _Alloc>::
     512              :     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
     513              :            const size_type __len2)
     514              :     {
     515              :       _M_check_length(__len1, __len2, "basic_string::_M_replace");
     516              : 
     517              :       const size_type __old_size = this->size();
     518              :       const size_type __new_size = __old_size + __len2 - __len1;
     519              : 
     520              :       if (__new_size <= this->capacity())
     521              :     {
     522              :       pointer __p = this->_M_data() + __pos;
     523              : 
     524              :       const size_type __how_much = __old_size - __pos - __len1;
     525              : #if __cpp_lib_is_constant_evaluated
     526              :       if (std::is_constant_evaluated())
     527              :         {
     528              :           auto __newp = _S_allocate(_M_get_allocator(), __new_size);
     529              :           _S_copy(__newp, this->_M_data(), __pos);
     530              :           _S_copy(__newp + __pos, __s, __len2);
     531              :           _S_copy(__newp + __pos + __len2, __p + __len1, __how_much);
     532              :           _S_copy(this->_M_data(), __newp, __new_size);
     533              :           this->_M_get_allocator().deallocate(__newp, __new_size);
     534              :         }
     535              :       else
     536              : #endif
     537              :       if (__builtin_expect(_M_disjunct(__s), true))
     538              :         {
     539              :           if (__how_much && __len1 != __len2)
     540              :         this->_S_move(__p + __len2, __p + __len1, __how_much);
     541              :           if (__len2)
     542              :         this->_S_copy(__p, __s, __len2);
     543              :         }
     544              :       else
     545              :         _M_replace_cold(__p, __len1, __s, __len2, __how_much);
     546              :     }
     547              :       else
     548              :     this->_M_mutate(__pos, __len1, __s, __len2);
     549              : 
     550              :       this->_M_set_length(__new_size);
     551              :       return *this;
     552              :     }
     553              : 
     554              :   template<typename _CharT, typename _Traits, typename _Alloc>
     555              :     _GLIBCXX20_CONSTEXPR
     556              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     557              :     basic_string<_CharT, _Traits, _Alloc>::
     558              :     copy(_CharT* __s, size_type __n, size_type __pos) const
     559              :     {
     560              :       _M_check(__pos, "basic_string::copy");
     561              :       __n = _M_limit(__pos, __n);
     562              :       __glibcxx_requires_string_len(__s, __n);
     563              :       if (__n)
     564              :     _S_copy(__s, _M_data() + __pos, __n);
     565              :       // 21.3.5.7 par 3: do not append null.  (good.)
     566              :       return __n;
     567              :     }
     568              : 
     569              : #ifdef __glibcxx_string_resize_and_overwrite // C++ >= 23
     570              :   template<typename _CharT, typename _Traits, typename _Alloc>
     571              :   template<typename _Operation>
     572              :     [[__gnu__::__always_inline__]]
     573              :     constexpr void
     574              :     basic_string<_CharT, _Traits, _Alloc>::
     575              :     __resize_and_overwrite(const size_type __n, _Operation __op)
     576              :     { resize_and_overwrite<_Operation&>(__n, __op); }
     577              : #endif
     578              : 
     579              : #if __cplusplus >= 201103L
     580              :   template<typename _CharT, typename _Traits, typename _Alloc>
     581              :   template<typename _Operation>
     582              :     _GLIBCXX20_CONSTEXPR void
     583              :     basic_string<_CharT, _Traits, _Alloc>::
     584              : #ifdef __glibcxx_string_resize_and_overwrite // C++ >= 23
     585              :     resize_and_overwrite(const size_type __n, _Operation __op)
     586              : #else
     587              :     __resize_and_overwrite(const size_type __n, _Operation __op)
     588              : #endif
     589              :     {
     590              :       reserve(__n);
     591              :       _CharT* const __p = _M_data();
     592              : #if __cpp_lib_is_constant_evaluated
     593              :       if (std::__is_constant_evaluated() && __n > size())
     594              :     traits_type::assign(__p + size(), __n - size(), _CharT());
     595              : #endif
     596              :       struct _Terminator {
     597              :     _GLIBCXX20_CONSTEXPR ~_Terminator() { _M_this->_M_set_length(_M_r); }
     598              :     basic_string* _M_this;
     599              :     size_type _M_r;
     600              :       };
     601              :       _Terminator __term{this, 0};
     602              :       auto __r = std::move(__op)(__p + 0, __n + 0);
     603              : #ifdef __cpp_lib_concepts
     604              :       static_assert(ranges::__detail::__is_integer_like<decltype(__r)>);
     605              : #else
     606              :       static_assert(__gnu_cxx::__is_integer_nonstrict<decltype(__r)>::__value,
     607              :             "resize_and_overwrite operation must return an integer");
     608              : #endif
     609              :       _GLIBCXX_DEBUG_ASSERT(__r >= 0 && size_type(__r) <= __n);
     610              :       __term._M_r = size_type(__r);
     611              :       if (__term._M_r > __n)
     612              :     __builtin_unreachable();
     613              :     }
     614              : #endif // C++11
     615              : 
     616              : #endif  // _GLIBCXX_USE_CXX11_ABI
     617              :    
     618              : #if __glibcxx_constexpr_string >= 201907L
     619              : # define _GLIBCXX_STRING_CONSTEXPR constexpr
     620              : #else
     621              : # define _GLIBCXX_STRING_CONSTEXPR
     622              : #endif
     623              :   template<typename _CharT, typename _Traits, typename _Alloc>
     624              :     _GLIBCXX_STRING_CONSTEXPR
     625              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     626              :     basic_string<_CharT, _Traits, _Alloc>::
     627              :     find(const _CharT* __s, size_type __pos, size_type __n) const
     628              :     _GLIBCXX_NOEXCEPT
     629              :     {
     630              :       __glibcxx_requires_string_len(__s, __n);
     631              :       const size_type __size = this->size();
     632              : 
     633              :       if (__n == 0)
     634              :     return __pos <= __size ? __pos : npos;
     635              :       if (__pos >= __size)
     636              :     return npos;
     637              : 
     638              :       const _CharT __elem0 = __s[0];
     639              :       const _CharT* const __data = data();
     640              :       const _CharT* __first = __data + __pos;
     641              :       const _CharT* const __last = __data + __size;
     642              :       size_type __len = __size - __pos;
     643              : 
     644              :       while (__len >= __n)
     645              :     {
     646              :       // Find the first occurrence of __elem0:
     647              :       __first = traits_type::find(__first, __len - __n + 1, __elem0);
     648              :       if (!__first)
     649              :         return npos;
     650              :       // Compare the full strings from the first occurrence of __elem0.
     651              :       // We already know that __first[0] == __s[0] but compare them again
     652              :       // anyway because __s is probably aligned, which helps memcmp.
     653              :       if (traits_type::compare(__first, __s, __n) == 0)
     654              :         return __first - __data;
     655              :       __len = __last - ++__first;
     656              :     }
     657              :       return npos;
     658              :     }
     659              : 
     660              :   template<typename _CharT, typename _Traits, typename _Alloc>
     661              :     _GLIBCXX_STRING_CONSTEXPR
     662              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     663              :     basic_string<_CharT, _Traits, _Alloc>::
     664              :     find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
     665              :     {
     666              :       size_type __ret = npos;
     667              :       const size_type __size = this->size();
     668              :       if (__pos < __size)
     669              :     {
     670              :       const _CharT* __data = _M_data();
     671              :       const size_type __n = __size - __pos;
     672              :       const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
     673              :       if (__p)
     674              :         __ret = __p - __data;
     675              :     }
     676              :       return __ret;
     677              :     }
     678              : 
     679              :   template<typename _CharT, typename _Traits, typename _Alloc>
     680              :     _GLIBCXX_STRING_CONSTEXPR
     681              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     682              :     basic_string<_CharT, _Traits, _Alloc>::
     683              :     rfind(const _CharT* __s, size_type __pos, size_type __n) const
     684              :     _GLIBCXX_NOEXCEPT
     685              :     {
     686              :       __glibcxx_requires_string_len(__s, __n);
     687              :       const size_type __size = this->size();
     688              :       if (__n <= __size)
     689              :     {
     690              :       __pos = std::min(size_type(__size - __n), __pos);
     691              :       const _CharT* __data = _M_data();
     692              :       do
     693              :         {
     694              :           if (traits_type::compare(__data + __pos, __s, __n) == 0)
     695              :         return __pos;
     696              :         }
     697              :       while (__pos-- > 0);
     698              :     }
     699              :       return npos;
     700              :     }
     701              : 
     702              :   template<typename _CharT, typename _Traits, typename _Alloc>
     703              :     _GLIBCXX_STRING_CONSTEXPR
     704              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     705              :     basic_string<_CharT, _Traits, _Alloc>::
     706              :     rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
     707              :     {
     708              :       size_type __size = this->size();
     709              :       if (__size)
     710              :     {
     711              :       if (--__size > __pos)
     712              :         __size = __pos;
     713              :       for (++__size; __size-- > 0; )
     714              :         if (traits_type::eq(_M_data()[__size], __c))
     715              :           return __size;
     716              :     }
     717              :       return npos;
     718              :     }
     719              : 
     720              :   template<typename _CharT, typename _Traits, typename _Alloc>
     721              :     _GLIBCXX_STRING_CONSTEXPR
     722              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     723              :     basic_string<_CharT, _Traits, _Alloc>::
     724              :     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
     725              :     _GLIBCXX_NOEXCEPT
     726              :     {
     727              :       __glibcxx_requires_string_len(__s, __n);
     728              :       for (; __n && __pos < this->size(); ++__pos)
     729              :     {
     730              :       const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
     731              :       if (__p)
     732              :         return __pos;
     733              :     }
     734              :       return npos;
     735              :     }
     736              : 
     737              :   template<typename _CharT, typename _Traits, typename _Alloc>
     738              :     _GLIBCXX_STRING_CONSTEXPR
     739              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     740              :     basic_string<_CharT, _Traits, _Alloc>::
     741              :     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
     742              :     _GLIBCXX_NOEXCEPT
     743              :     {
     744              :       __glibcxx_requires_string_len(__s, __n);
     745              :       size_type __size = this->size();
     746              :       if (__size && __n)
     747              :     {
     748              :       if (--__size > __pos)
     749              :         __size = __pos;
     750              :       do
     751              :         {
     752              :           if (traits_type::find(__s, __n, _M_data()[__size]))
     753              :         return __size;
     754              :         }
     755              :       while (__size-- != 0);
     756              :     }
     757              :       return npos;
     758              :     }
     759              : 
     760              :   template<typename _CharT, typename _Traits, typename _Alloc>
     761              :     _GLIBCXX_STRING_CONSTEXPR
     762              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     763              :     basic_string<_CharT, _Traits, _Alloc>::
     764              :     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
     765              :     _GLIBCXX_NOEXCEPT
     766              :     {
     767              :       __glibcxx_requires_string_len(__s, __n);
     768              :       for (; __pos < this->size(); ++__pos)
     769              :     if (!traits_type::find(__s, __n, _M_data()[__pos]))
     770              :       return __pos;
     771              :       return npos;
     772              :     }
     773              : 
     774              :   template<typename _CharT, typename _Traits, typename _Alloc>
     775              :     _GLIBCXX_STRING_CONSTEXPR
     776              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     777              :     basic_string<_CharT, _Traits, _Alloc>::
     778              :     find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
     779              :     {
     780              :       for (; __pos < this->size(); ++__pos)
     781              :     if (!traits_type::eq(_M_data()[__pos], __c))
     782              :       return __pos;
     783              :       return npos;
     784              :     }
     785              : 
     786              :   template<typename _CharT, typename _Traits, typename _Alloc>
     787              :     _GLIBCXX_STRING_CONSTEXPR
     788              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     789              :     basic_string<_CharT, _Traits, _Alloc>::
     790              :     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
     791              :     _GLIBCXX_NOEXCEPT
     792              :     {
     793              :       __glibcxx_requires_string_len(__s, __n);
     794              :       size_type __size = this->size();
     795              :       if (__size)
     796              :     {
     797              :       if (--__size > __pos)
     798              :         __size = __pos;
     799              :       do
     800              :         {
     801              :           if (!traits_type::find(__s, __n, _M_data()[__size]))
     802              :         return __size;
     803              :         }
     804              :       while (__size--);
     805              :     }
     806              :       return npos;
     807              :     }
     808              : 
     809              :   template<typename _CharT, typename _Traits, typename _Alloc>
     810              :     _GLIBCXX_STRING_CONSTEXPR
     811              :     typename basic_string<_CharT, _Traits, _Alloc>::size_type
     812              :     basic_string<_CharT, _Traits, _Alloc>::
     813              :     find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
     814              :     {
     815              :       size_type __size = this->size();
     816              :       if (__size)
     817              :     {
     818              :       if (--__size > __pos)
     819              :         __size = __pos;
     820              :       do
     821              :         {
     822              :           if (!traits_type::eq(_M_data()[__size], __c))
     823              :         return __size;
     824              :         }
     825              :       while (__size--);
     826              :     }
     827              :       return npos;
     828              :     }
     829              : 
     830              : #undef _GLIBCXX_STRING_CONSTEXPR
     831              : 
     832              :   // 21.3.7.9 basic_string::getline and operators
     833              :   template<typename _CharT, typename _Traits, typename _Alloc>
     834              :     basic_istream<_CharT, _Traits>&
     835              :     operator>>(basic_istream<_CharT, _Traits>& __in,
     836              :            basic_string<_CharT, _Traits, _Alloc>& __str)
     837              :     {
     838              :       typedef basic_istream<_CharT, _Traits>      __istream_type;
     839              :       typedef basic_string<_CharT, _Traits, _Alloc>   __string_type;
     840              :       typedef typename __istream_type::ios_base         __ios_base;
     841              :       typedef typename __istream_type::int_type     __int_type;
     842              :       typedef typename __string_type::size_type     __size_type;
     843              :       typedef ctype<_CharT>               __ctype_type;
     844              :       typedef typename __ctype_type::ctype_base         __ctype_base;
     845              : 
     846              :       __size_type __extracted = 0;
     847              :       typename __ios_base::iostate __err = __ios_base::goodbit;
     848              :       typename __istream_type::sentry __cerb(__in, false);
     849              :       if (__cerb)
     850              :     {
     851              :       __try
     852              :         {
     853              :           // Avoid reallocation for common case.
     854              :           __str.erase();
     855              :           _CharT __buf[128];
     856              :           __size_type __len = 0;          
     857              :           const streamsize __w = __in.width();
     858              :           const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
     859              :                                       : __str.max_size();
     860              :           const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
     861              :           const __int_type __eof = _Traits::eof();
     862              :           __int_type __c = __in.rdbuf()->sgetc();
     863              : 
     864              :           while (__extracted < __n
     865              :              && !_Traits::eq_int_type(__c, __eof)
     866              :              && !__ct.is(__ctype_base::space,
     867              :                  _Traits::to_char_type(__c)))
     868              :         {
     869              :           if (__len == sizeof(__buf) / sizeof(_CharT))
     870              :             {
     871              :               __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
     872              :               __len = 0;
     873              :             }
     874              :           __buf[__len++] = _Traits::to_char_type(__c);
     875              :           ++__extracted;
     876              :           __c = __in.rdbuf()->snextc();
     877              :         }
     878              :           __str.append(__buf, __len);
     879              : 
     880              :           if (__extracted < __n && _Traits::eq_int_type(__c, __eof))
     881              :         __err |= __ios_base::eofbit;
     882              :           __in.width(0);
     883              :         }
     884              :       __catch(__cxxabiv1::__forced_unwind&)
     885              :         {
     886              :           __in._M_setstate(__ios_base::badbit);
     887              :           __throw_exception_again;
     888              :         }
     889              :       __catch(...)
     890              :         {
     891              :           // _GLIBCXX_RESOLVE_LIB_DEFECTS
     892              :           // 91. Description of operator>> and getline() for string<>
     893              :           // might cause endless loop
     894              :           __in._M_setstate(__ios_base::badbit);
     895              :         }
     896              :     }
     897              :       // 211.  operator>>(istream&, string&) doesn't set failbit
     898              :       if (!__extracted)
     899              :     __err |= __ios_base::failbit;
     900              :       if (__err)
     901              :     __in.setstate(__err);
     902              :       return __in;
     903              :     }
     904              : 
     905              :   template<typename _CharT, typename _Traits, typename _Alloc>
     906              :     basic_istream<_CharT, _Traits>&
     907              :     getline(basic_istream<_CharT, _Traits>& __in,
     908              :         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
     909              :     {
     910              :       typedef basic_istream<_CharT, _Traits>      __istream_type;
     911              :       typedef basic_string<_CharT, _Traits, _Alloc>   __string_type;
     912              :       typedef typename __istream_type::ios_base         __ios_base;
     913              :       typedef typename __istream_type::int_type     __int_type;
     914              :       typedef typename __string_type::size_type     __size_type;
     915              : 
     916              :       __size_type __extracted = 0;
     917              :       const __size_type __n = __str.max_size();
     918              :       typename __ios_base::iostate __err = __ios_base::goodbit;
     919              :       typename __istream_type::sentry __cerb(__in, true);
     920              :       if (__cerb)
     921              :     {
     922              :       __try
     923              :         {
     924              :           __str.erase();
     925              :           const __int_type __idelim = _Traits::to_int_type(__delim);
     926              :           const __int_type __eof = _Traits::eof();
     927              :           __int_type __c = __in.rdbuf()->sgetc();
     928              : 
     929              :           while (__extracted < __n
     930              :              && !_Traits::eq_int_type(__c, __eof)
     931              :              && !_Traits::eq_int_type(__c, __idelim))
     932              :         {
     933              :           __str += _Traits::to_char_type(__c);
     934              :           ++__extracted;
     935              :           __c = __in.rdbuf()->snextc();
     936              :         }
     937              : 
     938              :           if (_Traits::eq_int_type(__c, __eof))
     939              :         __err |= __ios_base::eofbit;
     940              :           else if (_Traits::eq_int_type(__c, __idelim))
     941              :         {
     942              :           ++__extracted;          
     943              :           __in.rdbuf()->sbumpc();
     944              :         }
     945              :           else
     946              :         __err |= __ios_base::failbit;
     947              :         }
     948              :       __catch(__cxxabiv1::__forced_unwind&)
     949              :         {
     950              :           __in._M_setstate(__ios_base::badbit);
     951              :           __throw_exception_again;
     952              :         }
     953              :       __catch(...)
     954              :         {
     955              :           // _GLIBCXX_RESOLVE_LIB_DEFECTS
     956              :           // 91. Description of operator>> and getline() for string<>
     957              :           // might cause endless loop
     958              :           __in._M_setstate(__ios_base::badbit);
     959              :         }
     960              :     }
     961              :       if (!__extracted)
     962              :     __err |= __ios_base::failbit;
     963              :       if (__err)
     964              :     __in.setstate(__err);
     965              :       return __in;
     966              :     }
     967              : 
     968              :   // Inhibit implicit instantiations for required instantiations,
     969              :   // which are defined via explicit instantiations elsewhere.
     970              : #if _GLIBCXX_EXTERN_TEMPLATE
     971              :   // The explicit instantiation definitions in src/c++11/string-inst.cc and
     972              :   // src/c++17/string-inst.cc only instantiate the members required for C++17
     973              :   // and earlier standards (so not C++20's starts_with and ends_with).
     974              :   // Suppress the explicit instantiation declarations for C++20, so C++20
     975              :   // code will implicitly instantiate std::string and std::wstring as needed.
     976              : # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
     977              :   extern template class basic_string<char>;
     978              : # elif ! _GLIBCXX_USE_CXX11_ABI
     979              :   // Still need to prevent implicit instantiation of the COW empty rep,
     980              :   // to ensure the definition in libstdc++.so is unique (PR 86138).
     981              :   extern template basic_string<char>::size_type
     982              :     basic_string<char>::_Rep::_S_empty_rep_storage[];
     983              : # elif _GLIBCXX_EXTERN_TEMPLATE > 0
     984              :   // Export _M_replace_cold even for C++20.
     985              :   extern template void
     986              :     basic_string<char>::_M_replace_cold(char *, size_type, const char*,
     987              :                     const size_type, const size_type);
     988              : # endif
     989              : 
     990              :   extern template
     991              :     basic_istream<char>&
     992              :     operator>>(basic_istream<char>&, string&);
     993              :   extern template
     994              :     basic_ostream<char>&
     995              :     operator<<(basic_ostream<char>&, const string&);
     996              :   extern template
     997              :     basic_istream<char>&
     998              :     getline(basic_istream<char>&, string&, char);
     999              :   extern template
    1000              :     basic_istream<char>&
    1001              :     getline(basic_istream<char>&, string&);
    1002              : 
    1003              : #ifdef _GLIBCXX_USE_WCHAR_T
    1004              : # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
    1005              :   extern template class basic_string<wchar_t>;
    1006              : # elif ! _GLIBCXX_USE_CXX11_ABI
    1007              :   extern template basic_string<wchar_t>::size_type
    1008              :     basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];
    1009              : # elif _GLIBCXX_EXTERN_TEMPLATE > 0
    1010              :   // Export _M_replace_cold even for C++20.
    1011              :   extern template void
    1012              :     basic_string<wchar_t>::_M_replace_cold(wchar_t*, size_type, const wchar_t*,
    1013              :                        const size_type, const size_type);
    1014              : # endif
    1015              : 
    1016              :   extern template
    1017              :     basic_istream<wchar_t>&
    1018              :     operator>>(basic_istream<wchar_t>&, wstring&);
    1019              :   extern template
    1020              :     basic_ostream<wchar_t>&
    1021              :     operator<<(basic_ostream<wchar_t>&, const wstring&);
    1022              :   extern template
    1023              :     basic_istream<wchar_t>&
    1024              :     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
    1025              :   extern template
    1026              :     basic_istream<wchar_t>&
    1027              :     getline(basic_istream<wchar_t>&, wstring&);
    1028              : #endif // _GLIBCXX_USE_WCHAR_T
    1029              : #endif // _GLIBCXX_EXTERN_TEMPLATE
    1030              : 
    1031              : _GLIBCXX_END_NAMESPACE_VERSION
    1032              : } // namespace std
    1033              : 
    1034              : #endif
        

Generated by: LCOV version 2.0-1