xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/string_view.tcc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1b17d1066Smrg // Components for manipulating non-owning sequences of characters -*- C++ -*-
2b17d1066Smrg 
3*b1e83836Smrg // Copyright (C) 2013-2022 Free Software Foundation, Inc.
4b17d1066Smrg //
5b17d1066Smrg // This file is part of the GNU ISO C++ Library.  This library is free
6b17d1066Smrg // software; you can redistribute it and/or modify it under the
7b17d1066Smrg // terms of the GNU General Public License as published by the
8b17d1066Smrg // Free Software Foundation; either version 3, or (at your option)
9b17d1066Smrg // any later version.
10b17d1066Smrg 
11b17d1066Smrg // This library is distributed in the hope that it will be useful,
12b17d1066Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
13b17d1066Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b17d1066Smrg // GNU General Public License for more details.
15b17d1066Smrg 
16b17d1066Smrg // Under Section 7 of GPL version 3, you are granted additional
17b17d1066Smrg // permissions described in the GCC Runtime Library Exception, version
18b17d1066Smrg // 3.1, as published by the Free Software Foundation.
19b17d1066Smrg 
20b17d1066Smrg // You should have received a copy of the GNU General Public License and
21b17d1066Smrg // a copy of the GCC Runtime Library Exception along with this program;
22b17d1066Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23b17d1066Smrg // <http://www.gnu.org/licenses/>.
24b17d1066Smrg 
25a3e9eb18Smrg /** @file include/bits/string_view.tcc
26b17d1066Smrg  *  This is an internal header file, included by other library headers.
27b17d1066Smrg  *  Do not attempt to use it directly. @headername{string_view}
28b17d1066Smrg  */
29b17d1066Smrg 
30b17d1066Smrg //
31b17d1066Smrg // N3762 basic_string_view library
32b17d1066Smrg //
33b17d1066Smrg 
34b17d1066Smrg #ifndef _GLIBCXX_STRING_VIEW_TCC
35b17d1066Smrg #define _GLIBCXX_STRING_VIEW_TCC 1
36b17d1066Smrg 
37b17d1066Smrg #pragma GCC system_header
38b17d1066Smrg 
39b17d1066Smrg #if __cplusplus >= 201703L
40b17d1066Smrg 
41b17d1066Smrg namespace std _GLIBCXX_VISIBILITY(default)
42b17d1066Smrg {
43b17d1066Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
44b17d1066Smrg 
45b17d1066Smrg   template<typename _CharT, typename _Traits>
46b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
47b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find(const _CharT * __str,size_type __pos,size_type __n) const48b17d1066Smrg     find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
49b17d1066Smrg     {
50b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
51b17d1066Smrg 
52b17d1066Smrg       if (__n == 0)
53*b1e83836Smrg 	return __pos <= _M_len ? __pos : npos;
54*b1e83836Smrg       if (__pos >= _M_len)
55*b1e83836Smrg 	return npos;
56b17d1066Smrg 
57*b1e83836Smrg       const _CharT __elem0 = __str[0];
58*b1e83836Smrg       const _CharT* __first = _M_str + __pos;
59*b1e83836Smrg       const _CharT* const __last = _M_str + _M_len;
60*b1e83836Smrg       size_type __len = _M_len - __pos;
61*b1e83836Smrg 
62*b1e83836Smrg       while (__len >= __n)
63b17d1066Smrg 	{
64*b1e83836Smrg 	  // Find the first occurrence of __elem0:
65*b1e83836Smrg 	  __first = traits_type::find(__first, __len - __n + 1, __elem0);
66*b1e83836Smrg 	  if (!__first)
67*b1e83836Smrg 	    return npos;
68*b1e83836Smrg 	  // Compare the full strings from the first occurrence of __elem0.
69*b1e83836Smrg 	  // We already know that __first[0] == __s[0] but compare them again
70*b1e83836Smrg 	  // anyway because __s is probably aligned, which helps memcmp.
71*b1e83836Smrg 	  if (traits_type::compare(__first, __str, __n) == 0)
72*b1e83836Smrg 	    return __first - _M_str;
73*b1e83836Smrg 	  __len = __last - ++__first;
74b17d1066Smrg 	}
75b17d1066Smrg       return npos;
76b17d1066Smrg     }
77b17d1066Smrg 
78b17d1066Smrg   template<typename _CharT, typename _Traits>
79b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
80b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find(_CharT __c,size_type __pos) const81b17d1066Smrg     find(_CharT __c, size_type __pos) const noexcept
82b17d1066Smrg     {
83b17d1066Smrg       size_type __ret = npos;
84b17d1066Smrg       if (__pos < this->_M_len)
85b17d1066Smrg 	{
86b17d1066Smrg 	  const size_type __n = this->_M_len - __pos;
87b17d1066Smrg 	  const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c);
88b17d1066Smrg 	  if (__p)
89b17d1066Smrg 	    __ret = __p - this->_M_str;
90b17d1066Smrg 	}
91b17d1066Smrg       return __ret;
92b17d1066Smrg     }
93b17d1066Smrg 
94b17d1066Smrg   template<typename _CharT, typename _Traits>
95b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
96b17d1066Smrg     basic_string_view<_CharT, _Traits>::
rfind(const _CharT * __str,size_type __pos,size_type __n) const97b17d1066Smrg     rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
98b17d1066Smrg     {
99b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
100b17d1066Smrg 
101b17d1066Smrg       if (__n <= this->_M_len)
102b17d1066Smrg 	{
103b17d1066Smrg 	  __pos = std::min(size_type(this->_M_len - __n), __pos);
104b17d1066Smrg 	  do
105b17d1066Smrg 	    {
106b17d1066Smrg 	      if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0)
107b17d1066Smrg 		return __pos;
108b17d1066Smrg 	    }
109b17d1066Smrg 	  while (__pos-- > 0);
110b17d1066Smrg 	}
111b17d1066Smrg       return npos;
112b17d1066Smrg     }
113b17d1066Smrg 
114b17d1066Smrg   template<typename _CharT, typename _Traits>
115b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
116b17d1066Smrg     basic_string_view<_CharT, _Traits>::
rfind(_CharT __c,size_type __pos) const117b17d1066Smrg     rfind(_CharT __c, size_type __pos) const noexcept
118b17d1066Smrg     {
119b17d1066Smrg       size_type __size = this->_M_len;
120b17d1066Smrg       if (__size > 0)
121b17d1066Smrg 	{
122b17d1066Smrg 	  if (--__size > __pos)
123b17d1066Smrg 	    __size = __pos;
124b17d1066Smrg 	  for (++__size; __size-- > 0; )
125b17d1066Smrg 	    if (traits_type::eq(this->_M_str[__size], __c))
126b17d1066Smrg 	      return __size;
127b17d1066Smrg 	}
128b17d1066Smrg       return npos;
129b17d1066Smrg     }
130b17d1066Smrg 
131b17d1066Smrg   template<typename _CharT, typename _Traits>
132b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
133b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_first_of(const _CharT * __str,size_type __pos,size_type __n) const134a3e9eb18Smrg     find_first_of(const _CharT* __str, size_type __pos,
135a3e9eb18Smrg 		  size_type __n) const noexcept
136b17d1066Smrg     {
137b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
138b17d1066Smrg       for (; __n && __pos < this->_M_len; ++__pos)
139b17d1066Smrg 	{
140b17d1066Smrg 	  const _CharT* __p = traits_type::find(__str, __n,
141b17d1066Smrg 						this->_M_str[__pos]);
142b17d1066Smrg 	  if (__p)
143b17d1066Smrg 	    return __pos;
144b17d1066Smrg 	}
145b17d1066Smrg       return npos;
146b17d1066Smrg     }
147b17d1066Smrg 
148b17d1066Smrg   template<typename _CharT, typename _Traits>
149b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
150b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_last_of(const _CharT * __str,size_type __pos,size_type __n) const151a3e9eb18Smrg     find_last_of(const _CharT* __str, size_type __pos,
152a3e9eb18Smrg 		 size_type __n) const noexcept
153b17d1066Smrg     {
154b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
155b17d1066Smrg       size_type __size = this->size();
156b17d1066Smrg       if (__size && __n)
157b17d1066Smrg 	{
158b17d1066Smrg 	  if (--__size > __pos)
159b17d1066Smrg 	    __size = __pos;
160b17d1066Smrg 	  do
161b17d1066Smrg 	    {
162b17d1066Smrg 	      if (traits_type::find(__str, __n, this->_M_str[__size]))
163b17d1066Smrg 		return __size;
164b17d1066Smrg 	    }
165b17d1066Smrg 	  while (__size-- != 0);
166b17d1066Smrg 	}
167b17d1066Smrg       return npos;
168b17d1066Smrg     }
169b17d1066Smrg 
170b17d1066Smrg   template<typename _CharT, typename _Traits>
171b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
172b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_first_not_of(const _CharT * __str,size_type __pos,size_type __n) const173a3e9eb18Smrg     find_first_not_of(const _CharT* __str, size_type __pos,
174a3e9eb18Smrg 		      size_type __n) const noexcept
175b17d1066Smrg     {
176b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
177b17d1066Smrg       for (; __pos < this->_M_len; ++__pos)
178b17d1066Smrg 	if (!traits_type::find(__str, __n, this->_M_str[__pos]))
179b17d1066Smrg 	  return __pos;
180b17d1066Smrg       return npos;
181b17d1066Smrg     }
182b17d1066Smrg 
183b17d1066Smrg   template<typename _CharT, typename _Traits>
184b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
185b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_first_not_of(_CharT __c,size_type __pos) const186b17d1066Smrg     find_first_not_of(_CharT __c, size_type __pos) const noexcept
187b17d1066Smrg     {
188b17d1066Smrg       for (; __pos < this->_M_len; ++__pos)
189b17d1066Smrg 	if (!traits_type::eq(this->_M_str[__pos], __c))
190b17d1066Smrg 	  return __pos;
191b17d1066Smrg       return npos;
192b17d1066Smrg     }
193b17d1066Smrg 
194b17d1066Smrg   template<typename _CharT, typename _Traits>
195b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
196b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_last_not_of(const _CharT * __str,size_type __pos,size_type __n) const197a3e9eb18Smrg     find_last_not_of(const _CharT* __str, size_type __pos,
198a3e9eb18Smrg 		     size_type __n) const noexcept
199b17d1066Smrg     {
200b17d1066Smrg       __glibcxx_requires_string_len(__str, __n);
201b17d1066Smrg       size_type __size = this->_M_len;
202b17d1066Smrg       if (__size)
203b17d1066Smrg 	{
204b17d1066Smrg 	  if (--__size > __pos)
205b17d1066Smrg 	    __size = __pos;
206b17d1066Smrg 	  do
207b17d1066Smrg 	    {
208b17d1066Smrg 	      if (!traits_type::find(__str, __n, this->_M_str[__size]))
209b17d1066Smrg 		return __size;
210b17d1066Smrg 	    }
211b17d1066Smrg 	  while (__size--);
212b17d1066Smrg 	}
213b17d1066Smrg       return npos;
214b17d1066Smrg     }
215b17d1066Smrg 
216b17d1066Smrg   template<typename _CharT, typename _Traits>
217b17d1066Smrg     constexpr typename basic_string_view<_CharT, _Traits>::size_type
218b17d1066Smrg     basic_string_view<_CharT, _Traits>::
find_last_not_of(_CharT __c,size_type __pos) const219b17d1066Smrg     find_last_not_of(_CharT __c, size_type __pos) const noexcept
220b17d1066Smrg     {
221b17d1066Smrg       size_type __size = this->_M_len;
222b17d1066Smrg       if (__size)
223b17d1066Smrg 	{
224b17d1066Smrg 	  if (--__size > __pos)
225b17d1066Smrg 	    __size = __pos;
226b17d1066Smrg 	  do
227b17d1066Smrg 	    {
228b17d1066Smrg 	      if (!traits_type::eq(this->_M_str[__size], __c))
229b17d1066Smrg 		return __size;
230b17d1066Smrg 	    }
231b17d1066Smrg 	  while (__size--);
232b17d1066Smrg 	}
233b17d1066Smrg       return npos;
234b17d1066Smrg     }
235b17d1066Smrg 
236b17d1066Smrg _GLIBCXX_END_NAMESPACE_VERSION
237b17d1066Smrg } // namespace std
238b17d1066Smrg 
239b17d1066Smrg #endif // __cplusplus <= 201402L
240b17d1066Smrg 
241b17d1066Smrg #endif // _GLIBCXX_STRING_VIEW_TCC
242