Home | History | Annotate | Line # | Download | only in bits
      1 // Components for manipulating non-owning sequences of characters -*- C++ -*-
      2 
      3 // Copyright (C) 2013-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 include/bits/string_view.tcc
     26  *  This is an internal header file, included by other library headers.
     27  *  Do not attempt to use it directly. @headername{string_view}
     28  */
     29 
     30 //
     31 // N3762 basic_string_view library
     32 //
     33 
     34 #ifndef _GLIBCXX_STRING_VIEW_TCC
     35 #define _GLIBCXX_STRING_VIEW_TCC 1
     36 
     37 #pragma GCC system_header
     38 
     39 #if __cplusplus >= 201703L
     40 
     41 namespace std _GLIBCXX_VISIBILITY(default)
     42 {
     43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     44 
     45   template<typename _CharT, typename _Traits>
     46     constexpr typename basic_string_view<_CharT, _Traits>::size_type
     47     basic_string_view<_CharT, _Traits>::
     48     find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
     49     {
     50       __glibcxx_requires_string_len(__str, __n);
     51 
     52       if (__n == 0)
     53 	return __pos <= _M_len ? __pos : npos;
     54       if (__pos >= _M_len)
     55 	return npos;
     56 
     57       const _CharT __elem0 = __str[0];
     58       const _CharT* __first = _M_str + __pos;
     59       const _CharT* const __last = _M_str + _M_len;
     60       size_type __len = _M_len - __pos;
     61 
     62       while (__len >= __n)
     63 	{
     64 	  // Find the first occurrence of __elem0:
     65 	  __first = traits_type::find(__first, __len - __n + 1, __elem0);
     66 	  if (!__first)
     67 	    return npos;
     68 	  // Compare the full strings from the first occurrence of __elem0.
     69 	  // We already know that __first[0] == __s[0] but compare them again
     70 	  // anyway because __s is probably aligned, which helps memcmp.
     71 	  if (traits_type::compare(__first, __str, __n) == 0)
     72 	    return __first - _M_str;
     73 	  __len = __last - ++__first;
     74 	}
     75       return npos;
     76     }
     77 
     78   template<typename _CharT, typename _Traits>
     79     constexpr typename basic_string_view<_CharT, _Traits>::size_type
     80     basic_string_view<_CharT, _Traits>::
     81     find(_CharT __c, size_type __pos) const noexcept
     82     {
     83       size_type __ret = npos;
     84       if (__pos < this->_M_len)
     85 	{
     86 	  const size_type __n = this->_M_len - __pos;
     87 	  const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c);
     88 	  if (__p)
     89 	    __ret = __p - this->_M_str;
     90 	}
     91       return __ret;
     92     }
     93 
     94   template<typename _CharT, typename _Traits>
     95     constexpr typename basic_string_view<_CharT, _Traits>::size_type
     96     basic_string_view<_CharT, _Traits>::
     97     rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
     98     {
     99       __glibcxx_requires_string_len(__str, __n);
    100 
    101       if (__n <= this->_M_len)
    102 	{
    103 	  __pos = std::min(size_type(this->_M_len - __n), __pos);
    104 	  do
    105 	    {
    106 	      if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0)
    107 		return __pos;
    108 	    }
    109 	  while (__pos-- > 0);
    110 	}
    111       return npos;
    112     }
    113 
    114   template<typename _CharT, typename _Traits>
    115     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    116     basic_string_view<_CharT, _Traits>::
    117     rfind(_CharT __c, size_type __pos) const noexcept
    118     {
    119       size_type __size = this->_M_len;
    120       if (__size > 0)
    121 	{
    122 	  if (--__size > __pos)
    123 	    __size = __pos;
    124 	  for (++__size; __size-- > 0; )
    125 	    if (traits_type::eq(this->_M_str[__size], __c))
    126 	      return __size;
    127 	}
    128       return npos;
    129     }
    130 
    131   template<typename _CharT, typename _Traits>
    132     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    133     basic_string_view<_CharT, _Traits>::
    134     find_first_of(const _CharT* __str, size_type __pos,
    135 		  size_type __n) const noexcept
    136     {
    137       __glibcxx_requires_string_len(__str, __n);
    138       for (; __n && __pos < this->_M_len; ++__pos)
    139 	{
    140 	  const _CharT* __p = traits_type::find(__str, __n,
    141 						this->_M_str[__pos]);
    142 	  if (__p)
    143 	    return __pos;
    144 	}
    145       return npos;
    146     }
    147 
    148   template<typename _CharT, typename _Traits>
    149     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    150     basic_string_view<_CharT, _Traits>::
    151     find_last_of(const _CharT* __str, size_type __pos,
    152 		 size_type __n) const noexcept
    153     {
    154       __glibcxx_requires_string_len(__str, __n);
    155       size_type __size = this->size();
    156       if (__size && __n)
    157 	{
    158 	  if (--__size > __pos)
    159 	    __size = __pos;
    160 	  do
    161 	    {
    162 	      if (traits_type::find(__str, __n, this->_M_str[__size]))
    163 		return __size;
    164 	    }
    165 	  while (__size-- != 0);
    166 	}
    167       return npos;
    168     }
    169 
    170   template<typename _CharT, typename _Traits>
    171     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    172     basic_string_view<_CharT, _Traits>::
    173     find_first_not_of(const _CharT* __str, size_type __pos,
    174 		      size_type __n) const noexcept
    175     {
    176       __glibcxx_requires_string_len(__str, __n);
    177       for (; __pos < this->_M_len; ++__pos)
    178 	if (!traits_type::find(__str, __n, this->_M_str[__pos]))
    179 	  return __pos;
    180       return npos;
    181     }
    182 
    183   template<typename _CharT, typename _Traits>
    184     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    185     basic_string_view<_CharT, _Traits>::
    186     find_first_not_of(_CharT __c, size_type __pos) const noexcept
    187     {
    188       for (; __pos < this->_M_len; ++__pos)
    189 	if (!traits_type::eq(this->_M_str[__pos], __c))
    190 	  return __pos;
    191       return npos;
    192     }
    193 
    194   template<typename _CharT, typename _Traits>
    195     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    196     basic_string_view<_CharT, _Traits>::
    197     find_last_not_of(const _CharT* __str, size_type __pos,
    198 		     size_type __n) const noexcept
    199     {
    200       __glibcxx_requires_string_len(__str, __n);
    201       size_type __size = this->_M_len;
    202       if (__size)
    203 	{
    204 	  if (--__size > __pos)
    205 	    __size = __pos;
    206 	  do
    207 	    {
    208 	      if (!traits_type::find(__str, __n, this->_M_str[__size]))
    209 		return __size;
    210 	    }
    211 	  while (__size--);
    212 	}
    213       return npos;
    214     }
    215 
    216   template<typename _CharT, typename _Traits>
    217     constexpr typename basic_string_view<_CharT, _Traits>::size_type
    218     basic_string_view<_CharT, _Traits>::
    219     find_last_not_of(_CharT __c, size_type __pos) const noexcept
    220     {
    221       size_type __size = this->_M_len;
    222       if (__size)
    223 	{
    224 	  if (--__size > __pos)
    225 	    __size = __pos;
    226 	  do
    227 	    {
    228 	      if (!traits_type::eq(this->_M_str[__size], __c))
    229 		return __size;
    230 	    }
    231 	  while (__size--);
    232 	}
    233       return npos;
    234     }
    235 
    236 _GLIBCXX_END_NAMESPACE_VERSION
    237 } // namespace std
    238 
    239 #endif // __cplusplus <= 201402L
    240 
    241 #endif // _GLIBCXX_STRING_VIEW_TCC
    242