blob: 1bbfbbacf959d156b77de763d39811691286aeca [file] [log] [blame]
Marshall Clow053d81c2016-07-21 05:31:24 +00001// -*- C++ -*-
2//===-------------------------- __string ----------------------------------===//
3//
Chandler Carruth2946cd72019-01-19 08:50:56 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Marshall Clow053d81c2016-07-21 05:31:24 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STRING
11#define _LIBCPP___STRING
12
13/*
14 string synopsis
15
16namespace std
17{
18
19template <class charT>
20struct char_traits
21{
22 typedef charT char_type;
23 typedef ... int_type;
24 typedef streamoff off_type;
25 typedef streampos pos_type;
26 typedef mbstate_t state_type;
27
Marshall Clow05d57fa2017-01-12 04:37:14 +000028 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
Marshall Clow053d81c2016-07-21 05:31:24 +000029 static constexpr bool eq(char_type c1, char_type c2) noexcept;
30 static constexpr bool lt(char_type c1, char_type c2) noexcept;
31
Marshall Clow05d57fa2017-01-12 04:37:14 +000032 static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
33 static constexpr size_t length(const char_type* s);
Louis Dionne6b77ebd2019-10-23 10:40:15 -070034 static constexpr const char_type*
Marshall Clow05d57fa2017-01-12 04:37:14 +000035 find(const char_type* s, size_t n, const char_type& a);
Michael Parkeb8710c2019-11-08 13:42:26 +000036
37 static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
38 static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
39 static constexpr char_type* assign(char_type* s, size_t n, char_type a); // constexpr in C++20
Marshall Clow053d81c2016-07-21 05:31:24 +000040
41 static constexpr int_type not_eof(int_type c) noexcept;
42 static constexpr char_type to_char_type(int_type c) noexcept;
43 static constexpr int_type to_int_type(char_type c) noexcept;
44 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
45 static constexpr int_type eof() noexcept;
46};
47
48template <> struct char_traits<char>;
49template <> struct char_traits<wchar_t>;
Marshall Clow7dad0bd2018-12-11 04:35:44 +000050template <> struct char_traits<char8_t>; // c++20
Marshall Clow053d81c2016-07-21 05:31:24 +000051
52} // std
53
54*/
55
56#include <__config>
57#include <algorithm> // for search and min
58#include <cstdio> // For EOF.
59#include <memory> // for __murmur2_or_cityhash
60
Marshall Clow053d81c2016-07-21 05:31:24 +000061#include <__debug>
62
63#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64#pragma GCC system_header
65#endif
66
Eric Fiseliera016efb2017-05-31 22:07:49 +000067_LIBCPP_PUSH_MACROS
68#include <__undef_macros>
69
70
Marshall Clow053d81c2016-07-21 05:31:24 +000071_LIBCPP_BEGIN_NAMESPACE_STD
72
Eric Fiselier61bd1922020-01-09 15:50:55 -050073// The the extern template ABI lists are kept outside of <string> to improve the
74// readability of that header.
75
76#define _LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
77 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
78 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
79 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
80 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
81 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
82 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \
83 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
84 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
85 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
86 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
87 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
88 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
89 _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
90 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
91 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
92 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
93 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
94 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
95 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
96 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
97 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
98 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \
99 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
100 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
101 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
102 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
103 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
104 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
105 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
106 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
107 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
108 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
109 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
110 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
111 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
112 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
113 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
114 _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
115 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
116 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
117 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
118 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
119 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
120 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
121 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
122 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
123 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
124 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
125
126
Marshall Clow053d81c2016-07-21 05:31:24 +0000127// char_traits
128
129template <class _CharT>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000130struct _LIBCPP_TEMPLATE_VIS char_traits
Marshall Clow053d81c2016-07-21 05:31:24 +0000131{
132 typedef _CharT char_type;
133 typedef int int_type;
134 typedef streamoff off_type;
135 typedef streampos pos_type;
136 typedef mbstate_t state_type;
137
Marshall Clow05d57fa2017-01-12 04:37:14 +0000138 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
139 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clow053d81c2016-07-21 05:31:24 +0000140 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
141 {return __c1 == __c2;}
142 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
143 {return __c1 < __c2;}
144
Marshall Clow05d57fa2017-01-12 04:37:14 +0000145 static _LIBCPP_CONSTEXPR_AFTER_CXX14
146 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
147 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
148 size_t length(const char_type* __s);
149 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
150 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
Michael Parkeb8710c2019-11-08 13:42:26 +0000151 static _LIBCPP_CONSTEXPR_AFTER_CXX17
152 char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
Marshall Clow053d81c2016-07-21 05:31:24 +0000153 _LIBCPP_INLINE_VISIBILITY
Michael Parkeb8710c2019-11-08 13:42:26 +0000154 static _LIBCPP_CONSTEXPR_AFTER_CXX17
155 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
Marshall Clow053d81c2016-07-21 05:31:24 +0000156 _LIBCPP_INLINE_VISIBILITY
Michael Parkeb8710c2019-11-08 13:42:26 +0000157 static _LIBCPP_CONSTEXPR_AFTER_CXX17
158 char_type* assign(char_type* __s, size_t __n, char_type __a);
Marshall Clow053d81c2016-07-21 05:31:24 +0000159
160 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
161 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
162 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
163 {return char_type(__c);}
164 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
165 {return int_type(__c);}
166 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
167 {return __c1 == __c2;}
168 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
169 {return int_type(EOF);}
170};
171
172template <class _CharT>
Marshall Clow05d57fa2017-01-12 04:37:14 +0000173_LIBCPP_CONSTEXPR_AFTER_CXX14 int
Marshall Clow053d81c2016-07-21 05:31:24 +0000174char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
175{
176 for (; __n; --__n, ++__s1, ++__s2)
177 {
178 if (lt(*__s1, *__s2))
179 return -1;
180 if (lt(*__s2, *__s1))
181 return 1;
182 }
183 return 0;
184}
185
186template <class _CharT>
187inline
Marshall Clow05d57fa2017-01-12 04:37:14 +0000188_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
Marshall Clow053d81c2016-07-21 05:31:24 +0000189char_traits<_CharT>::length(const char_type* __s)
190{
191 size_t __len = 0;
192 for (; !eq(*__s, char_type(0)); ++__s)
193 ++__len;
194 return __len;
195}
196
197template <class _CharT>
198inline
Marshall Clow05d57fa2017-01-12 04:37:14 +0000199_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
Marshall Clow053d81c2016-07-21 05:31:24 +0000200char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
201{
202 for (; __n; --__n)
203 {
204 if (eq(*__s, __a))
205 return __s;
206 ++__s;
207 }
208 return 0;
209}
210
211template <class _CharT>
Michael Parkeb8710c2019-11-08 13:42:26 +0000212_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT*
Marshall Clow053d81c2016-07-21 05:31:24 +0000213char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
214{
Michael Parkeb8710c2019-11-08 13:42:26 +0000215 if (__n == 0) return __s1;
Marshall Clow053d81c2016-07-21 05:31:24 +0000216 char_type* __r = __s1;
217 if (__s1 < __s2)
218 {
219 for (; __n; --__n, ++__s1, ++__s2)
220 assign(*__s1, *__s2);
221 }
222 else if (__s2 < __s1)
223 {
224 __s1 += __n;
225 __s2 += __n;
226 for (; __n; --__n)
227 assign(*--__s1, *--__s2);
228 }
229 return __r;
230}
231
232template <class _CharT>
Michael Parkeb8710c2019-11-08 13:42:26 +0000233inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000234_CharT*
235char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
236{
237 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
238 char_type* __r = __s1;
239 for (; __n; --__n, ++__s1, ++__s2)
240 assign(*__s1, *__s2);
241 return __r;
242}
243
244template <class _CharT>
Michael Parkeb8710c2019-11-08 13:42:26 +0000245inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000246_CharT*
247char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
248{
249 char_type* __r = __s;
250 for (; __n; --__n, ++__s)
251 assign(*__s, __a);
252 return __r;
253}
254
Michael Parkeb8710c2019-11-08 13:42:26 +0000255// constexpr versions of move/copy/assign.
256
257template <class _CharT>
258static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
259_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
260{
261 if (__n == 0) return __s1;
262 if (__s1 < __s2) {
263 _VSTD::copy(__s2, __s2 + __n, __s1);
264 } else if (__s2 < __s1) {
265 _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
266 }
267 return __s1;
268}
269
270template <class _CharT>
271static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
272_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
273{
274 _VSTD::copy_n(__s2, __n, __s1);
275 return __s1;
276}
277
278template <class _CharT>
279static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
280_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
281{
282 _VSTD::fill_n(__s, __n, __a);
283 return __s;
284}
285
Marshall Clow053d81c2016-07-21 05:31:24 +0000286// char_traits<char>
287
288template <>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000289struct _LIBCPP_TEMPLATE_VIS char_traits<char>
Marshall Clow053d81c2016-07-21 05:31:24 +0000290{
291 typedef char char_type;
292 typedef int int_type;
293 typedef streamoff off_type;
294 typedef streampos pos_type;
295 typedef mbstate_t state_type;
296
Marshall Clow05d57fa2017-01-12 04:37:14 +0000297 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
298 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clow053d81c2016-07-21 05:31:24 +0000299 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
300 {return __c1 == __c2;}
301 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
302 {return (unsigned char)__c1 < (unsigned char)__c2;}
303
Marshall Clow9087bbe2017-01-12 05:40:58 +0000304 static _LIBCPP_CONSTEXPR_AFTER_CXX14
305 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow05d57fa2017-01-12 04:37:14 +0000306 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
307 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
308 static _LIBCPP_CONSTEXPR_AFTER_CXX14
309 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000310 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
311 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
312 {
313 return __libcpp_is_constant_evaluated()
314 ? __move_constexpr(__s1, __s2, __n)
315 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
316 }
317 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
318 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000319 {
320 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkeb8710c2019-11-08 13:42:26 +0000321 return __libcpp_is_constant_evaluated()
322 ? __copy_constexpr(__s1, __s2, __n)
323 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
Marshall Clow053d81c2016-07-21 05:31:24 +0000324 }
Michael Parkeb8710c2019-11-08 13:42:26 +0000325 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
326 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
327 {
328 return __libcpp_is_constant_evaluated()
329 ? __assign_constexpr(__s, __n, __a)
330 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
331 }
Marshall Clow053d81c2016-07-21 05:31:24 +0000332
333 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
334 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
335 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
336 {return char_type(__c);}
337 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
338 {return int_type((unsigned char)__c);}
339 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
340 {return __c1 == __c2;}
341 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
342 {return int_type(EOF);}
343};
344
Marshall Clow05d57fa2017-01-12 04:37:14 +0000345inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow9087bbe2017-01-12 05:40:58 +0000346int
347char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
348{
349 if (__n == 0)
350 return 0;
Marshall Clow3a3c09c2017-01-26 06:58:29 +0000351#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow9087bbe2017-01-12 05:40:58 +0000352 return __builtin_memcmp(__s1, __s2, __n);
353#elif _LIBCPP_STD_VER <= 14
354 return memcmp(__s1, __s2, __n);
355#else
356 for (; __n; --__n, ++__s1, ++__s2)
357 {
358 if (lt(*__s1, *__s2))
359 return -1;
360 if (lt(*__s2, *__s1))
361 return 1;
362 }
363 return 0;
364#endif
365}
366
367inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow05d57fa2017-01-12 04:37:14 +0000368const char*
369char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
370{
371 if (__n == 0)
Marshall Clowf951fc32018-02-06 18:58:05 +0000372 return nullptr;
Marshall Clow3a3c09c2017-01-26 06:58:29 +0000373#if __has_feature(cxx_constexpr_string_builtins)
374 return __builtin_char_memchr(__s, to_int_type(__a), __n);
375#elif _LIBCPP_STD_VER <= 14
Marshall Clow05d57fa2017-01-12 04:37:14 +0000376 return (const char_type*) memchr(__s, to_int_type(__a), __n);
377#else
378 for (; __n; --__n)
379 {
380 if (eq(*__s, __a))
381 return __s;
382 ++__s;
383 }
Marshall Clowf951fc32018-02-06 18:58:05 +0000384 return nullptr;
Marshall Clow05d57fa2017-01-12 04:37:14 +0000385#endif
386}
387
388
Marshall Clow053d81c2016-07-21 05:31:24 +0000389// char_traits<wchar_t>
390
391template <>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000392struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
Marshall Clow053d81c2016-07-21 05:31:24 +0000393{
394 typedef wchar_t char_type;
395 typedef wint_t int_type;
396 typedef streamoff off_type;
397 typedef streampos pos_type;
398 typedef mbstate_t state_type;
399
Marshall Clow05d57fa2017-01-12 04:37:14 +0000400 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
401 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clow053d81c2016-07-21 05:31:24 +0000402 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
403 {return __c1 == __c2;}
404 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
405 {return __c1 < __c2;}
406
Marshall Clow05d57fa2017-01-12 04:37:14 +0000407 static _LIBCPP_CONSTEXPR_AFTER_CXX14
408 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
409 static _LIBCPP_CONSTEXPR_AFTER_CXX14
410 size_t length(const char_type* __s) _NOEXCEPT;
411 static _LIBCPP_CONSTEXPR_AFTER_CXX14
412 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000413 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
414 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
415 {
416 return __libcpp_is_constant_evaluated()
417 ? __move_constexpr(__s1, __s2, __n)
418 : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n);
419 }
420 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
421 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000422 {
423 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkeb8710c2019-11-08 13:42:26 +0000424 return __libcpp_is_constant_evaluated()
425 ? __copy_constexpr(__s1, __s2, __n)
426 : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n);
Marshall Clow053d81c2016-07-21 05:31:24 +0000427 }
Michael Parkeb8710c2019-11-08 13:42:26 +0000428 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
429 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
430 {
431 return __libcpp_is_constant_evaluated()
432 ? __assign_constexpr(__s, __n, __a)
433 : __n == 0 ? __s : wmemset(__s, __a, __n);
434 }
Marshall Clow053d81c2016-07-21 05:31:24 +0000435 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
436 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
437 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
438 {return char_type(__c);}
439 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
440 {return int_type(__c);}
441 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
442 {return __c1 == __c2;}
443 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
444 {return int_type(WEOF);}
445};
446
Marshall Clow05d57fa2017-01-12 04:37:14 +0000447inline _LIBCPP_CONSTEXPR_AFTER_CXX14
448int
449char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
450{
451 if (__n == 0)
452 return 0;
Marshall Clow3a3c09c2017-01-26 06:58:29 +0000453#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow05d57fa2017-01-12 04:37:14 +0000454 return __builtin_wmemcmp(__s1, __s2, __n);
455#elif _LIBCPP_STD_VER <= 14
456 return wmemcmp(__s1, __s2, __n);
457#else
458 for (; __n; --__n, ++__s1, ++__s2)
459 {
460 if (lt(*__s1, *__s2))
461 return -1;
462 if (lt(*__s2, *__s1))
463 return 1;
464 }
465 return 0;
466#endif
467}
468
Eric Fiselier6bc12362019-09-14 19:55:28 +0000469
470template <class _Traits>
471_LIBCPP_INLINE_VISIBILITY
472_LIBCPP_CONSTEXPR
473inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
474#if _LIBCPP_DEBUG_LEVEL >= 1
475 return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0);
476#else
477 return _Traits::length(__s);
478#endif
479}
480
Marshall Clow05d57fa2017-01-12 04:37:14 +0000481inline _LIBCPP_CONSTEXPR_AFTER_CXX14
482size_t
483char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
484{
Marshall Clow3a3c09c2017-01-26 06:58:29 +0000485#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow05d57fa2017-01-12 04:37:14 +0000486 return __builtin_wcslen(__s);
487#elif _LIBCPP_STD_VER <= 14
488 return wcslen(__s);
489#else
490 size_t __len = 0;
491 for (; !eq(*__s, char_type(0)); ++__s)
492 ++__len;
493 return __len;
494#endif
495}
496
497inline _LIBCPP_CONSTEXPR_AFTER_CXX14
498const wchar_t*
499char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
500{
501 if (__n == 0)
Marshall Clowf951fc32018-02-06 18:58:05 +0000502 return nullptr;
Marshall Clow3a3c09c2017-01-26 06:58:29 +0000503#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clowf951fc32018-02-06 18:58:05 +0000504 return __builtin_wmemchr(__s, __a, __n);
Marshall Clow05d57fa2017-01-12 04:37:14 +0000505#elif _LIBCPP_STD_VER <= 14
506 return wmemchr(__s, __a, __n);
507#else
508 for (; __n; --__n)
509 {
510 if (eq(*__s, __a))
511 return __s;
512 ++__s;
513 }
Marshall Clowf951fc32018-02-06 18:58:05 +0000514 return nullptr;
Marshall Clow05d57fa2017-01-12 04:37:14 +0000515#endif
516}
517
518
Marshall Clow7dad0bd2018-12-11 04:35:44 +0000519#ifndef _LIBCPP_NO_HAS_CHAR8_T
520
521template <>
522struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
523{
524 typedef char8_t char_type;
525 typedef unsigned int int_type;
526 typedef streamoff off_type;
527 typedef u8streampos pos_type;
528 typedef mbstate_t state_type;
529
530 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
531 {__c1 = __c2;}
532 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
533 {return __c1 == __c2;}
534 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
535 {return __c1 < __c2;}
536
537 static constexpr
538 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
539
540 static constexpr
541 size_t length(const char_type* __s) _NOEXCEPT;
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700542
Marshall Clow7dad0bd2018-12-11 04:35:44 +0000543 _LIBCPP_INLINE_VISIBILITY static constexpr
544 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700545
Michael Parkeb8710c2019-11-08 13:42:26 +0000546 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
547 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
548 {
549 return __libcpp_is_constant_evaluated()
550 ? __move_constexpr(__s1, __s2, __n)
551 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
552 }
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700553
Michael Parkeb8710c2019-11-08 13:42:26 +0000554 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
555 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow7dad0bd2018-12-11 04:35:44 +0000556 {
557 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkeb8710c2019-11-08 13:42:26 +0000558 return __libcpp_is_constant_evaluated()
559 ? __copy_constexpr(__s1, __s2, __n)
560 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
561 }
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700562
Michael Parkeb8710c2019-11-08 13:42:26 +0000563 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
564 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
565 {
566 return __libcpp_is_constant_evaluated()
567 ? __assign_constexpr(__s, __n, __a)
568 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
569 }
Marshall Clow7dad0bd2018-12-11 04:35:44 +0000570
571 static inline constexpr int_type not_eof(int_type __c) noexcept
572 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
573 static inline constexpr char_type to_char_type(int_type __c) noexcept
574 {return char_type(__c);}
575 static inline constexpr int_type to_int_type(char_type __c) noexcept
576 {return int_type(__c);}
577 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
578 {return __c1 == __c2;}
579 static inline constexpr int_type eof() noexcept
580 {return int_type(EOF);}
581};
582
583// TODO use '__builtin_strlen' if it ever supports char8_t ??
584inline constexpr
585size_t
586char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
587{
588 size_t __len = 0;
589 for (; !eq(*__s, char_type(0)); ++__s)
590 ++__len;
591 return __len;
592}
593
594inline constexpr
595int
596char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
597{
598#if __has_feature(cxx_constexpr_string_builtins)
599 return __builtin_memcmp(__s1, __s2, __n);
600#else
601 for (; __n; --__n, ++__s1, ++__s2)
602 {
603 if (lt(*__s1, *__s2))
604 return -1;
605 if (lt(*__s2, *__s1))
606 return 1;
607 }
608 return 0;
609#endif
610}
611
612// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
613inline constexpr
614const char8_t*
615char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
616{
617 for (; __n; --__n)
618 {
619 if (eq(*__s, __a))
620 return __s;
621 ++__s;
622 }
623 return 0;
624}
625
626#endif // #_LIBCPP_NO_HAS_CHAR8_T
627
Marshall Clow053d81c2016-07-21 05:31:24 +0000628#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
629
630template <>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000631struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
Marshall Clow053d81c2016-07-21 05:31:24 +0000632{
633 typedef char16_t char_type;
634 typedef uint_least16_t int_type;
635 typedef streamoff off_type;
636 typedef u16streampos pos_type;
637 typedef mbstate_t state_type;
638
Marshall Clow05d57fa2017-01-12 04:37:14 +0000639 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
640 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clow053d81c2016-07-21 05:31:24 +0000641 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
642 {return __c1 == __c2;}
643 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
644 {return __c1 < __c2;}
645
Marshall Clow05d57fa2017-01-12 04:37:14 +0000646 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
647 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
648 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
649 size_t length(const char_type* __s) _NOEXCEPT;
650 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
651 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000652 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000653 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000654 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000655 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000656 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000657 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clow053d81c2016-07-21 05:31:24 +0000658
659 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
660 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
661 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
662 {return char_type(__c);}
663 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
664 {return int_type(__c);}
665 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
666 {return __c1 == __c2;}
667 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
668 {return int_type(0xFFFF);}
669};
670
Marshall Clow05d57fa2017-01-12 04:37:14 +0000671inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000672int
Marshall Clowaa849bc2016-07-28 04:52:02 +0000673char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000674{
675 for (; __n; --__n, ++__s1, ++__s2)
676 {
677 if (lt(*__s1, *__s2))
678 return -1;
679 if (lt(*__s2, *__s1))
680 return 1;
681 }
682 return 0;
683}
684
Marshall Clow05d57fa2017-01-12 04:37:14 +0000685inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000686size_t
Marshall Clowaa849bc2016-07-28 04:52:02 +0000687char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000688{
689 size_t __len = 0;
690 for (; !eq(*__s, char_type(0)); ++__s)
691 ++__len;
692 return __len;
693}
694
Marshall Clow05d57fa2017-01-12 04:37:14 +0000695inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000696const char16_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000697char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000698{
699 for (; __n; --__n)
700 {
701 if (eq(*__s, __a))
702 return __s;
703 ++__s;
704 }
705 return 0;
706}
707
Michael Parkeb8710c2019-11-08 13:42:26 +0000708inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000709char16_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000710char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000711{
Michael Parkeb8710c2019-11-08 13:42:26 +0000712 if (__n == 0) return __s1;
Marshall Clow053d81c2016-07-21 05:31:24 +0000713 char_type* __r = __s1;
714 if (__s1 < __s2)
715 {
716 for (; __n; --__n, ++__s1, ++__s2)
717 assign(*__s1, *__s2);
718 }
719 else if (__s2 < __s1)
720 {
721 __s1 += __n;
722 __s2 += __n;
723 for (; __n; --__n)
724 assign(*--__s1, *--__s2);
725 }
726 return __r;
727}
728
Michael Parkeb8710c2019-11-08 13:42:26 +0000729inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000730char16_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000731char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000732{
733 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
734 char_type* __r = __s1;
735 for (; __n; --__n, ++__s1, ++__s2)
736 assign(*__s1, *__s2);
737 return __r;
738}
739
Michael Parkeb8710c2019-11-08 13:42:26 +0000740inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000741char16_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000742char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000743{
744 char_type* __r = __s;
745 for (; __n; --__n, ++__s)
746 assign(*__s, __a);
747 return __r;
748}
749
750template <>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000751struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
Marshall Clow053d81c2016-07-21 05:31:24 +0000752{
753 typedef char32_t char_type;
754 typedef uint_least32_t int_type;
755 typedef streamoff off_type;
756 typedef u32streampos pos_type;
757 typedef mbstate_t state_type;
758
Marshall Clow05d57fa2017-01-12 04:37:14 +0000759 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
760 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clow053d81c2016-07-21 05:31:24 +0000761 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
762 {return __c1 == __c2;}
763 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
764 {return __c1 < __c2;}
765
Marshall Clow05d57fa2017-01-12 04:37:14 +0000766 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
767 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
768 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
769 size_t length(const char_type* __s) _NOEXCEPT;
770 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
771 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000772 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000773 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000774 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000775 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkeb8710c2019-11-08 13:42:26 +0000776 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowaa849bc2016-07-28 04:52:02 +0000777 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clow053d81c2016-07-21 05:31:24 +0000778
779 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
780 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
781 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
782 {return char_type(__c);}
783 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
784 {return int_type(__c);}
785 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
786 {return __c1 == __c2;}
787 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
788 {return int_type(0xFFFFFFFF);}
789};
790
Marshall Clow05d57fa2017-01-12 04:37:14 +0000791inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000792int
Marshall Clowaa849bc2016-07-28 04:52:02 +0000793char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000794{
795 for (; __n; --__n, ++__s1, ++__s2)
796 {
797 if (lt(*__s1, *__s2))
798 return -1;
799 if (lt(*__s2, *__s1))
800 return 1;
801 }
802 return 0;
803}
804
Marshall Clow05d57fa2017-01-12 04:37:14 +0000805inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000806size_t
Marshall Clowaa849bc2016-07-28 04:52:02 +0000807char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000808{
809 size_t __len = 0;
810 for (; !eq(*__s, char_type(0)); ++__s)
811 ++__len;
812 return __len;
813}
814
Marshall Clow05d57fa2017-01-12 04:37:14 +0000815inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow053d81c2016-07-21 05:31:24 +0000816const char32_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000817char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000818{
819 for (; __n; --__n)
820 {
821 if (eq(*__s, __a))
822 return __s;
823 ++__s;
824 }
825 return 0;
826}
827
Michael Parkeb8710c2019-11-08 13:42:26 +0000828inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000829char32_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000830char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000831{
Michael Parkeb8710c2019-11-08 13:42:26 +0000832 if (__n == 0) return __s1;
Marshall Clow053d81c2016-07-21 05:31:24 +0000833 char_type* __r = __s1;
834 if (__s1 < __s2)
835 {
836 for (; __n; --__n, ++__s1, ++__s2)
837 assign(*__s1, *__s2);
838 }
839 else if (__s2 < __s1)
840 {
841 __s1 += __n;
842 __s2 += __n;
843 for (; __n; --__n)
844 assign(*--__s1, *--__s2);
845 }
846 return __r;
847}
848
Michael Parkeb8710c2019-11-08 13:42:26 +0000849inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000850char32_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000851char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000852{
853 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
854 char_type* __r = __s1;
855 for (; __n; --__n, ++__s1, ++__s2)
856 assign(*__s1, *__s2);
857 return __r;
858}
859
Michael Parkeb8710c2019-11-08 13:42:26 +0000860inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow053d81c2016-07-21 05:31:24 +0000861char32_t*
Marshall Clowaa849bc2016-07-28 04:52:02 +0000862char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow053d81c2016-07-21 05:31:24 +0000863{
864 char_type* __r = __s;
865 for (; __n; --__n, ++__s)
866 assign(*__s, __a);
867 return __r;
868}
869
870#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
871
872// helper fns for basic_string and string_view
873
874// __str_find
875template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
876inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700877__str_find(const _CharT *__p, _SizeT __sz,
Marshall Clow053d81c2016-07-21 05:31:24 +0000878 _CharT __c, _SizeT __pos) _NOEXCEPT
879{
880 if (__pos >= __sz)
881 return __npos;
882 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
883 if (__r == 0)
884 return __npos;
885 return static_cast<_SizeT>(__r - __p);
886}
887
Sebastian Pop90705002016-12-30 18:01:36 +0000888template <class _CharT, class _Traits>
889inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
890__search_substring(const _CharT *__first1, const _CharT *__last1,
891 const _CharT *__first2, const _CharT *__last2) {
892 // Take advantage of knowing source and pattern lengths.
893 // Stop short when source is smaller than pattern.
894 const ptrdiff_t __len2 = __last2 - __first2;
895 if (__len2 == 0)
896 return __first1;
897
898 ptrdiff_t __len1 = __last1 - __first1;
899 if (__len1 < __len2)
900 return __last1;
901
902 // First element of __first2 is loop invariant.
903 _CharT __f2 = *__first2;
904 while (true) {
905 __len1 = __last1 - __first1;
906 // Check whether __first1 still has at least __len2 bytes.
907 if (__len1 < __len2)
908 return __last1;
909
910 // Find __f2 the first byte matching in __first1.
911 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
912 if (__first1 == 0)
913 return __last1;
914
915 // It is faster to compare from the first byte of __first1 even if we
916 // already know that it matches the first byte of __first2: this is because
917 // __first2 is most likely aligned, as it is user's "pattern" string, and
918 // __first1 + 1 is most likely not aligned, as the match is in the middle of
919 // the string.
920 if (_Traits::compare(__first1, __first2, __len2) == 0)
921 return __first1;
922
923 ++__first1;
924 }
925}
926
Marshall Clow053d81c2016-07-21 05:31:24 +0000927template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
928inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700929__str_find(const _CharT *__p, _SizeT __sz,
Marshall Clow053d81c2016-07-21 05:31:24 +0000930 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
931{
Sebastian Pop90705002016-12-30 18:01:36 +0000932 if (__pos > __sz)
Marshall Clow053d81c2016-07-21 05:31:24 +0000933 return __npos;
Sebastian Pop90705002016-12-30 18:01:36 +0000934
935 if (__n == 0) // There is nothing to search, just return __pos.
Marshall Clow053d81c2016-07-21 05:31:24 +0000936 return __pos;
Sebastian Pop90705002016-12-30 18:01:36 +0000937
938 const _CharT *__r = __search_substring<_CharT, _Traits>(
939 __p + __pos, __p + __sz, __s, __s + __n);
940
Marshall Clow053d81c2016-07-21 05:31:24 +0000941 if (__r == __p + __sz)
942 return __npos;
943 return static_cast<_SizeT>(__r - __p);
944}
945
946
947// __str_rfind
948
949template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
950inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700951__str_rfind(const _CharT *__p, _SizeT __sz,
Marshall Clow053d81c2016-07-21 05:31:24 +0000952 _CharT __c, _SizeT __pos) _NOEXCEPT
953{
954 if (__sz < 1)
955 return __npos;
956 if (__pos < __sz)
957 ++__pos;
958 else
959 __pos = __sz;
960 for (const _CharT* __ps = __p + __pos; __ps != __p;)
961 {
962 if (_Traits::eq(*--__ps, __c))
963 return static_cast<_SizeT>(__ps - __p);
964 }
965 return __npos;
966}
967
968template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
969inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700970__str_rfind(const _CharT *__p, _SizeT __sz,
Marshall Clow053d81c2016-07-21 05:31:24 +0000971 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
972{
973 __pos = _VSTD::min(__pos, __sz);
974 if (__n < __sz - __pos)
975 __pos += __n;
976 else
977 __pos = __sz;
978 const _CharT* __r = _VSTD::__find_end(
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700979 __p, __p + __pos, __s, __s + __n, _Traits::eq,
Marshall Clow053d81c2016-07-21 05:31:24 +0000980 random_access_iterator_tag(), random_access_iterator_tag());
981 if (__n > 0 && __r == __p + __pos)
982 return __npos;
983 return static_cast<_SizeT>(__r - __p);
984}
985
986// __str_find_first_of
987template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
988inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
989__str_find_first_of(const _CharT *__p, _SizeT __sz,
990 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
991{
992 if (__pos >= __sz || __n == 0)
993 return __npos;
994 const _CharT* __r = _VSTD::__find_first_of_ce
995 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
996 if (__r == __p + __sz)
997 return __npos;
998 return static_cast<_SizeT>(__r - __p);
999}
1000
1001
1002// __str_find_last_of
1003template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1004inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1005__str_find_last_of(const _CharT *__p, _SizeT __sz,
1006 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1007 {
1008 if (__n != 0)
1009 {
1010 if (__pos < __sz)
1011 ++__pos;
1012 else
1013 __pos = __sz;
1014 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1015 {
1016 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
1017 if (__r)
1018 return static_cast<_SizeT>(__ps - __p);
1019 }
1020 }
1021 return __npos;
1022}
1023
1024
1025// __str_find_first_not_of
1026template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1027inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1028__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1029 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1030{
1031 if (__pos < __sz)
1032 {
1033 const _CharT* __pe = __p + __sz;
1034 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1035 if (_Traits::find(__s, __n, *__ps) == 0)
1036 return static_cast<_SizeT>(__ps - __p);
1037 }
1038 return __npos;
1039}
1040
1041
1042template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1043inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1044__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1045 _CharT __c, _SizeT __pos) _NOEXCEPT
1046{
1047 if (__pos < __sz)
1048 {
1049 const _CharT* __pe = __p + __sz;
1050 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1051 if (!_Traits::eq(*__ps, __c))
1052 return static_cast<_SizeT>(__ps - __p);
1053 }
1054 return __npos;
1055}
1056
1057
1058// __str_find_last_not_of
1059template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1060inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1061__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1062 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1063{
1064 if (__pos < __sz)
1065 ++__pos;
1066 else
1067 __pos = __sz;
1068 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1069 if (_Traits::find(__s, __n, *--__ps) == 0)
1070 return static_cast<_SizeT>(__ps - __p);
1071 return __npos;
1072}
1073
1074
1075template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1076inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1077__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1078 _CharT __c, _SizeT __pos) _NOEXCEPT
1079{
1080 if (__pos < __sz)
1081 ++__pos;
1082 else
1083 __pos = __sz;
1084 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1085 if (!_Traits::eq(*--__ps, __c))
1086 return static_cast<_SizeT>(__ps - __p);
1087 return __npos;
1088}
1089
1090template<class _Ptr>
Eric Fiselier49e29672016-09-15 22:27:07 +00001091inline _LIBCPP_INLINE_VISIBILITY
1092size_t __do_string_hash(_Ptr __p, _Ptr __e)
Marshall Clow053d81c2016-07-21 05:31:24 +00001093{
1094 typedef typename iterator_traits<_Ptr>::value_type value_type;
1095 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
1096}
1097
1098template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
1099struct __quoted_output_proxy
1100{
1101 _Iter __first;
1102 _Iter __last;
1103 _CharT __delim;
1104 _CharT __escape;
1105
1106 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
1107 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
Louis Dionne6b77ebd2019-10-23 10:40:15 -07001108 // This would be a nice place for a string_ref
Marshall Clow053d81c2016-07-21 05:31:24 +00001109};
1110
1111_LIBCPP_END_NAMESPACE_STD
1112
Eric Fiseliera016efb2017-05-31 22:07:49 +00001113_LIBCPP_POP_MACROS
1114
Marshall Clow053d81c2016-07-21 05:31:24 +00001115#endif // _LIBCPP___STRING