comparison libcxx/include/__string @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
comparison
equal deleted inserted replaced
147:c2174574ed3a 150:1d019706d866
1 // -*- C++ -*-
2 //===-------------------------- __string ----------------------------------===//
3 //
4 // 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
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP___STRING
11 #define _LIBCPP___STRING
12
13 /*
14 string synopsis
15
16 namespace std
17 {
18
19 template <class charT>
20 struct 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
28 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
29 static constexpr bool eq(char_type c1, char_type c2) noexcept;
30 static constexpr bool lt(char_type c1, char_type c2) noexcept;
31
32 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);
34 static constexpr const char_type*
35 find(const char_type* s, size_t n, const char_type& a);
36
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
40
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
48 template <> struct char_traits<char>;
49 template <> struct char_traits<wchar_t>;
50 template <> struct char_traits<char8_t>; // c++20
51
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
61 #include <__debug>
62
63 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64 #pragma GCC system_header
65 #endif
66
67 _LIBCPP_PUSH_MACROS
68 #include <__undef_macros>
69
70
71 _LIBCPP_BEGIN_NAMESPACE_STD
72
73 // The the extern template ABI lists are kept outside of <string> to improve the
74 // readability of that header.
75 #define _LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
76 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
77 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
78 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
79 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
80 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
81 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \
82 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
83 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
84 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
85 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
86 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
87 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
88 _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
89 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
90 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
91 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
92 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
93 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
94 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
95 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
96 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
97 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \
98 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
99 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
100 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
101 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
102 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
103 _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*)) \
104 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
105 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
106 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
107 _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
108 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
109 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
110 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
111 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
112 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
113 _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
114 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
115 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
116 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
117 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
118 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
119 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
120 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
121 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
122 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
123 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
124
125
126 // char_traits
127
128 template <class _CharT>
129 struct _LIBCPP_TEMPLATE_VIS char_traits
130 {
131 typedef _CharT char_type;
132 typedef int int_type;
133 typedef streamoff off_type;
134 typedef streampos pos_type;
135 typedef mbstate_t state_type;
136
137 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
138 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
139 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
140 {return __c1 == __c2;}
141 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
142 {return __c1 < __c2;}
143
144 static _LIBCPP_CONSTEXPR_AFTER_CXX14
145 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
146 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
147 size_t length(const char_type* __s);
148 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
149 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
150 static _LIBCPP_CONSTEXPR_AFTER_CXX17
151 char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
152 _LIBCPP_INLINE_VISIBILITY
153 static _LIBCPP_CONSTEXPR_AFTER_CXX17
154 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
155 _LIBCPP_INLINE_VISIBILITY
156 static _LIBCPP_CONSTEXPR_AFTER_CXX17
157 char_type* assign(char_type* __s, size_t __n, char_type __a);
158
159 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
160 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
161 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
162 {return char_type(__c);}
163 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
164 {return int_type(__c);}
165 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
166 {return __c1 == __c2;}
167 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
168 {return int_type(EOF);}
169 };
170
171 template <class _CharT>
172 _LIBCPP_CONSTEXPR_AFTER_CXX14 int
173 char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
174 {
175 for (; __n; --__n, ++__s1, ++__s2)
176 {
177 if (lt(*__s1, *__s2))
178 return -1;
179 if (lt(*__s2, *__s1))
180 return 1;
181 }
182 return 0;
183 }
184
185 template <class _CharT>
186 inline
187 _LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
188 char_traits<_CharT>::length(const char_type* __s)
189 {
190 size_t __len = 0;
191 for (; !eq(*__s, char_type(0)); ++__s)
192 ++__len;
193 return __len;
194 }
195
196 template <class _CharT>
197 inline
198 _LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
199 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
200 {
201 for (; __n; --__n)
202 {
203 if (eq(*__s, __a))
204 return __s;
205 ++__s;
206 }
207 return 0;
208 }
209
210 template <class _CharT>
211 _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT*
212 char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
213 {
214 if (__n == 0) return __s1;
215 char_type* __r = __s1;
216 if (__s1 < __s2)
217 {
218 for (; __n; --__n, ++__s1, ++__s2)
219 assign(*__s1, *__s2);
220 }
221 else if (__s2 < __s1)
222 {
223 __s1 += __n;
224 __s2 += __n;
225 for (; __n; --__n)
226 assign(*--__s1, *--__s2);
227 }
228 return __r;
229 }
230
231 template <class _CharT>
232 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
233 _CharT*
234 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
235 {
236 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
237 char_type* __r = __s1;
238 for (; __n; --__n, ++__s1, ++__s2)
239 assign(*__s1, *__s2);
240 return __r;
241 }
242
243 template <class _CharT>
244 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
245 _CharT*
246 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
247 {
248 char_type* __r = __s;
249 for (; __n; --__n, ++__s)
250 assign(*__s, __a);
251 return __r;
252 }
253
254 // constexpr versions of move/copy/assign.
255
256 template <class _CharT>
257 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
258 _CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
259 {
260 if (__n == 0) return __s1;
261 if (__s1 < __s2) {
262 _VSTD::copy(__s2, __s2 + __n, __s1);
263 } else if (__s2 < __s1) {
264 _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
265 }
266 return __s1;
267 }
268
269 template <class _CharT>
270 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
271 _CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
272 {
273 _VSTD::copy_n(__s2, __n, __s1);
274 return __s1;
275 }
276
277 template <class _CharT>
278 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
279 _CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
280 {
281 _VSTD::fill_n(__s, __n, __a);
282 return __s;
283 }
284
285 // char_traits<char>
286
287 template <>
288 struct _LIBCPP_TEMPLATE_VIS char_traits<char>
289 {
290 typedef char char_type;
291 typedef int int_type;
292 typedef streamoff off_type;
293 typedef streampos pos_type;
294 typedef mbstate_t state_type;
295
296 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
297 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
298 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
299 {return __c1 == __c2;}
300 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
301 {return (unsigned char)__c1 < (unsigned char)__c2;}
302
303 static _LIBCPP_CONSTEXPR_AFTER_CXX14
304 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
305 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
306 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
307 static _LIBCPP_CONSTEXPR_AFTER_CXX14
308 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
309 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
310 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
311 {
312 return __libcpp_is_constant_evaluated()
313 ? __move_constexpr(__s1, __s2, __n)
314 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
315 }
316 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
317 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
318 {
319 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
320 return __libcpp_is_constant_evaluated()
321 ? __copy_constexpr(__s1, __s2, __n)
322 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
323 }
324 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
325 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
326 {
327 return __libcpp_is_constant_evaluated()
328 ? __assign_constexpr(__s, __n, __a)
329 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
330 }
331
332 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
333 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
334 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
335 {return char_type(__c);}
336 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
337 {return int_type((unsigned char)__c);}
338 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
339 {return __c1 == __c2;}
340 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
341 {return int_type(EOF);}
342 };
343
344 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
345 int
346 char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
347 {
348 if (__n == 0)
349 return 0;
350 #if __has_feature(cxx_constexpr_string_builtins)
351 return __builtin_memcmp(__s1, __s2, __n);
352 #elif _LIBCPP_STD_VER <= 14
353 return memcmp(__s1, __s2, __n);
354 #else
355 for (; __n; --__n, ++__s1, ++__s2)
356 {
357 if (lt(*__s1, *__s2))
358 return -1;
359 if (lt(*__s2, *__s1))
360 return 1;
361 }
362 return 0;
363 #endif
364 }
365
366 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
367 const char*
368 char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
369 {
370 if (__n == 0)
371 return nullptr;
372 #if __has_feature(cxx_constexpr_string_builtins)
373 return __builtin_char_memchr(__s, to_int_type(__a), __n);
374 #elif _LIBCPP_STD_VER <= 14
375 return (const char_type*) memchr(__s, to_int_type(__a), __n);
376 #else
377 for (; __n; --__n)
378 {
379 if (eq(*__s, __a))
380 return __s;
381 ++__s;
382 }
383 return nullptr;
384 #endif
385 }
386
387
388 // char_traits<wchar_t>
389
390 template <>
391 struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
392 {
393 typedef wchar_t char_type;
394 typedef wint_t int_type;
395 typedef streamoff off_type;
396 typedef streampos pos_type;
397 typedef mbstate_t state_type;
398
399 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
400 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
401 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
402 {return __c1 == __c2;}
403 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
404 {return __c1 < __c2;}
405
406 static _LIBCPP_CONSTEXPR_AFTER_CXX14
407 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
408 static _LIBCPP_CONSTEXPR_AFTER_CXX14
409 size_t length(const char_type* __s) _NOEXCEPT;
410 static _LIBCPP_CONSTEXPR_AFTER_CXX14
411 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
412 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
413 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
414 {
415 return __libcpp_is_constant_evaluated()
416 ? __move_constexpr(__s1, __s2, __n)
417 : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n);
418 }
419 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
420 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
421 {
422 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
423 return __libcpp_is_constant_evaluated()
424 ? __copy_constexpr(__s1, __s2, __n)
425 : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n);
426 }
427 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
428 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
429 {
430 return __libcpp_is_constant_evaluated()
431 ? __assign_constexpr(__s, __n, __a)
432 : __n == 0 ? __s : wmemset(__s, __a, __n);
433 }
434 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
435 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
436 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
437 {return char_type(__c);}
438 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
439 {return int_type(__c);}
440 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
441 {return __c1 == __c2;}
442 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
443 {return int_type(WEOF);}
444 };
445
446 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
447 int
448 char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
449 {
450 if (__n == 0)
451 return 0;
452 #if __has_feature(cxx_constexpr_string_builtins)
453 return __builtin_wmemcmp(__s1, __s2, __n);
454 #elif _LIBCPP_STD_VER <= 14
455 return wmemcmp(__s1, __s2, __n);
456 #else
457 for (; __n; --__n, ++__s1, ++__s2)
458 {
459 if (lt(*__s1, *__s2))
460 return -1;
461 if (lt(*__s2, *__s1))
462 return 1;
463 }
464 return 0;
465 #endif
466 }
467
468
469 template <class _Traits>
470 _LIBCPP_INLINE_VISIBILITY
471 _LIBCPP_CONSTEXPR
472 inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
473 #if _LIBCPP_DEBUG_LEVEL >= 1
474 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);
475 #else
476 return _Traits::length(__s);
477 #endif
478 }
479
480 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
481 size_t
482 char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
483 {
484 #if __has_feature(cxx_constexpr_string_builtins)
485 return __builtin_wcslen(__s);
486 #elif _LIBCPP_STD_VER <= 14
487 return wcslen(__s);
488 #else
489 size_t __len = 0;
490 for (; !eq(*__s, char_type(0)); ++__s)
491 ++__len;
492 return __len;
493 #endif
494 }
495
496 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
497 const wchar_t*
498 char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
499 {
500 if (__n == 0)
501 return nullptr;
502 #if __has_feature(cxx_constexpr_string_builtins)
503 return __builtin_wmemchr(__s, __a, __n);
504 #elif _LIBCPP_STD_VER <= 14
505 return wmemchr(__s, __a, __n);
506 #else
507 for (; __n; --__n)
508 {
509 if (eq(*__s, __a))
510 return __s;
511 ++__s;
512 }
513 return nullptr;
514 #endif
515 }
516
517
518 #ifndef _LIBCPP_NO_HAS_CHAR8_T
519
520 template <>
521 struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
522 {
523 typedef char8_t char_type;
524 typedef unsigned int int_type;
525 typedef streamoff off_type;
526 typedef u8streampos pos_type;
527 typedef mbstate_t state_type;
528
529 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
530 {__c1 = __c2;}
531 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
532 {return __c1 == __c2;}
533 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
534 {return __c1 < __c2;}
535
536 static constexpr
537 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
538
539 static constexpr
540 size_t length(const char_type* __s) _NOEXCEPT;
541
542 _LIBCPP_INLINE_VISIBILITY static constexpr
543 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
544
545 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
546 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
547 {
548 return __libcpp_is_constant_evaluated()
549 ? __move_constexpr(__s1, __s2, __n)
550 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
551 }
552
553 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
554 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
555 {
556 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
557 return __libcpp_is_constant_evaluated()
558 ? __copy_constexpr(__s1, __s2, __n)
559 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
560 }
561
562 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
563 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
564 {
565 return __libcpp_is_constant_evaluated()
566 ? __assign_constexpr(__s, __n, __a)
567 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
568 }
569
570 static inline constexpr int_type not_eof(int_type __c) noexcept
571 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
572 static inline constexpr char_type to_char_type(int_type __c) noexcept
573 {return char_type(__c);}
574 static inline constexpr int_type to_int_type(char_type __c) noexcept
575 {return int_type(__c);}
576 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
577 {return __c1 == __c2;}
578 static inline constexpr int_type eof() noexcept
579 {return int_type(EOF);}
580 };
581
582 // TODO use '__builtin_strlen' if it ever supports char8_t ??
583 inline constexpr
584 size_t
585 char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
586 {
587 size_t __len = 0;
588 for (; !eq(*__s, char_type(0)); ++__s)
589 ++__len;
590 return __len;
591 }
592
593 inline constexpr
594 int
595 char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
596 {
597 #if __has_feature(cxx_constexpr_string_builtins)
598 return __builtin_memcmp(__s1, __s2, __n);
599 #else
600 for (; __n; --__n, ++__s1, ++__s2)
601 {
602 if (lt(*__s1, *__s2))
603 return -1;
604 if (lt(*__s2, *__s1))
605 return 1;
606 }
607 return 0;
608 #endif
609 }
610
611 // TODO use '__builtin_char_memchr' if it ever supports char8_t ??
612 inline constexpr
613 const char8_t*
614 char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
615 {
616 for (; __n; --__n)
617 {
618 if (eq(*__s, __a))
619 return __s;
620 ++__s;
621 }
622 return 0;
623 }
624
625 #endif // #_LIBCPP_NO_HAS_CHAR8_T
626
627 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
628
629 template <>
630 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
631 {
632 typedef char16_t char_type;
633 typedef uint_least16_t int_type;
634 typedef streamoff off_type;
635 typedef u16streampos pos_type;
636 typedef mbstate_t state_type;
637
638 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
639 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
640 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
641 {return __c1 == __c2;}
642 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
643 {return __c1 < __c2;}
644
645 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
646 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
647 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
648 size_t length(const char_type* __s) _NOEXCEPT;
649 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
650 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
651 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
652 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
653 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
655 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
656 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
657
658 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
659 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
660 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
661 {return char_type(__c);}
662 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
663 {return int_type(__c);}
664 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
665 {return __c1 == __c2;}
666 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
667 {return int_type(0xFFFF);}
668 };
669
670 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
671 int
672 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
673 {
674 for (; __n; --__n, ++__s1, ++__s2)
675 {
676 if (lt(*__s1, *__s2))
677 return -1;
678 if (lt(*__s2, *__s1))
679 return 1;
680 }
681 return 0;
682 }
683
684 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
685 size_t
686 char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
687 {
688 size_t __len = 0;
689 for (; !eq(*__s, char_type(0)); ++__s)
690 ++__len;
691 return __len;
692 }
693
694 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
695 const char16_t*
696 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
697 {
698 for (; __n; --__n)
699 {
700 if (eq(*__s, __a))
701 return __s;
702 ++__s;
703 }
704 return 0;
705 }
706
707 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
708 char16_t*
709 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
710 {
711 if (__n == 0) return __s1;
712 char_type* __r = __s1;
713 if (__s1 < __s2)
714 {
715 for (; __n; --__n, ++__s1, ++__s2)
716 assign(*__s1, *__s2);
717 }
718 else if (__s2 < __s1)
719 {
720 __s1 += __n;
721 __s2 += __n;
722 for (; __n; --__n)
723 assign(*--__s1, *--__s2);
724 }
725 return __r;
726 }
727
728 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
729 char16_t*
730 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
731 {
732 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
733 char_type* __r = __s1;
734 for (; __n; --__n, ++__s1, ++__s2)
735 assign(*__s1, *__s2);
736 return __r;
737 }
738
739 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
740 char16_t*
741 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
742 {
743 char_type* __r = __s;
744 for (; __n; --__n, ++__s)
745 assign(*__s, __a);
746 return __r;
747 }
748
749 template <>
750 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
751 {
752 typedef char32_t char_type;
753 typedef uint_least32_t int_type;
754 typedef streamoff off_type;
755 typedef u32streampos pos_type;
756 typedef mbstate_t state_type;
757
758 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
759 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
760 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
761 {return __c1 == __c2;}
762 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
763 {return __c1 < __c2;}
764
765 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
766 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
767 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
768 size_t length(const char_type* __s) _NOEXCEPT;
769 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
770 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
771 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
772 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
773 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
774 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
775 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
776 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
777
778 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
779 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
780 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
781 {return char_type(__c);}
782 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
783 {return int_type(__c);}
784 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
785 {return __c1 == __c2;}
786 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
787 {return int_type(0xFFFFFFFF);}
788 };
789
790 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
791 int
792 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
793 {
794 for (; __n; --__n, ++__s1, ++__s2)
795 {
796 if (lt(*__s1, *__s2))
797 return -1;
798 if (lt(*__s2, *__s1))
799 return 1;
800 }
801 return 0;
802 }
803
804 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
805 size_t
806 char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
807 {
808 size_t __len = 0;
809 for (; !eq(*__s, char_type(0)); ++__s)
810 ++__len;
811 return __len;
812 }
813
814 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
815 const char32_t*
816 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
817 {
818 for (; __n; --__n)
819 {
820 if (eq(*__s, __a))
821 return __s;
822 ++__s;
823 }
824 return 0;
825 }
826
827 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
828 char32_t*
829 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
830 {
831 if (__n == 0) return __s1;
832 char_type* __r = __s1;
833 if (__s1 < __s2)
834 {
835 for (; __n; --__n, ++__s1, ++__s2)
836 assign(*__s1, *__s2);
837 }
838 else if (__s2 < __s1)
839 {
840 __s1 += __n;
841 __s2 += __n;
842 for (; __n; --__n)
843 assign(*--__s1, *--__s2);
844 }
845 return __r;
846 }
847
848 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
849 char32_t*
850 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
851 {
852 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
853 char_type* __r = __s1;
854 for (; __n; --__n, ++__s1, ++__s2)
855 assign(*__s1, *__s2);
856 return __r;
857 }
858
859 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
860 char32_t*
861 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
862 {
863 char_type* __r = __s;
864 for (; __n; --__n, ++__s)
865 assign(*__s, __a);
866 return __r;
867 }
868
869 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
870
871 // helper fns for basic_string and string_view
872
873 // __str_find
874 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
875 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
876 __str_find(const _CharT *__p, _SizeT __sz,
877 _CharT __c, _SizeT __pos) _NOEXCEPT
878 {
879 if (__pos >= __sz)
880 return __npos;
881 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
882 if (__r == 0)
883 return __npos;
884 return static_cast<_SizeT>(__r - __p);
885 }
886
887 template <class _CharT, class _Traits>
888 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
889 __search_substring(const _CharT *__first1, const _CharT *__last1,
890 const _CharT *__first2, const _CharT *__last2) {
891 // Take advantage of knowing source and pattern lengths.
892 // Stop short when source is smaller than pattern.
893 const ptrdiff_t __len2 = __last2 - __first2;
894 if (__len2 == 0)
895 return __first1;
896
897 ptrdiff_t __len1 = __last1 - __first1;
898 if (__len1 < __len2)
899 return __last1;
900
901 // First element of __first2 is loop invariant.
902 _CharT __f2 = *__first2;
903 while (true) {
904 __len1 = __last1 - __first1;
905 // Check whether __first1 still has at least __len2 bytes.
906 if (__len1 < __len2)
907 return __last1;
908
909 // Find __f2 the first byte matching in __first1.
910 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
911 if (__first1 == 0)
912 return __last1;
913
914 // It is faster to compare from the first byte of __first1 even if we
915 // already know that it matches the first byte of __first2: this is because
916 // __first2 is most likely aligned, as it is user's "pattern" string, and
917 // __first1 + 1 is most likely not aligned, as the match is in the middle of
918 // the string.
919 if (_Traits::compare(__first1, __first2, __len2) == 0)
920 return __first1;
921
922 ++__first1;
923 }
924 }
925
926 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
927 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
928 __str_find(const _CharT *__p, _SizeT __sz,
929 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
930 {
931 if (__pos > __sz)
932 return __npos;
933
934 if (__n == 0) // There is nothing to search, just return __pos.
935 return __pos;
936
937 const _CharT *__r = __search_substring<_CharT, _Traits>(
938 __p + __pos, __p + __sz, __s, __s + __n);
939
940 if (__r == __p + __sz)
941 return __npos;
942 return static_cast<_SizeT>(__r - __p);
943 }
944
945
946 // __str_rfind
947
948 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
949 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
950 __str_rfind(const _CharT *__p, _SizeT __sz,
951 _CharT __c, _SizeT __pos) _NOEXCEPT
952 {
953 if (__sz < 1)
954 return __npos;
955 if (__pos < __sz)
956 ++__pos;
957 else
958 __pos = __sz;
959 for (const _CharT* __ps = __p + __pos; __ps != __p;)
960 {
961 if (_Traits::eq(*--__ps, __c))
962 return static_cast<_SizeT>(__ps - __p);
963 }
964 return __npos;
965 }
966
967 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
968 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
969 __str_rfind(const _CharT *__p, _SizeT __sz,
970 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
971 {
972 __pos = _VSTD::min(__pos, __sz);
973 if (__n < __sz - __pos)
974 __pos += __n;
975 else
976 __pos = __sz;
977 const _CharT* __r = _VSTD::__find_end(
978 __p, __p + __pos, __s, __s + __n, _Traits::eq,
979 random_access_iterator_tag(), random_access_iterator_tag());
980 if (__n > 0 && __r == __p + __pos)
981 return __npos;
982 return static_cast<_SizeT>(__r - __p);
983 }
984
985 // __str_find_first_of
986 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
987 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
988 __str_find_first_of(const _CharT *__p, _SizeT __sz,
989 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
990 {
991 if (__pos >= __sz || __n == 0)
992 return __npos;
993 const _CharT* __r = _VSTD::__find_first_of_ce
994 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
995 if (__r == __p + __sz)
996 return __npos;
997 return static_cast<_SizeT>(__r - __p);
998 }
999
1000
1001 // __str_find_last_of
1002 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1003 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1004 __str_find_last_of(const _CharT *__p, _SizeT __sz,
1005 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1006 {
1007 if (__n != 0)
1008 {
1009 if (__pos < __sz)
1010 ++__pos;
1011 else
1012 __pos = __sz;
1013 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1014 {
1015 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
1016 if (__r)
1017 return static_cast<_SizeT>(__ps - __p);
1018 }
1019 }
1020 return __npos;
1021 }
1022
1023
1024 // __str_find_first_not_of
1025 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1026 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1027 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1028 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1029 {
1030 if (__pos < __sz)
1031 {
1032 const _CharT* __pe = __p + __sz;
1033 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1034 if (_Traits::find(__s, __n, *__ps) == 0)
1035 return static_cast<_SizeT>(__ps - __p);
1036 }
1037 return __npos;
1038 }
1039
1040
1041 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1042 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1043 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1044 _CharT __c, _SizeT __pos) _NOEXCEPT
1045 {
1046 if (__pos < __sz)
1047 {
1048 const _CharT* __pe = __p + __sz;
1049 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1050 if (!_Traits::eq(*__ps, __c))
1051 return static_cast<_SizeT>(__ps - __p);
1052 }
1053 return __npos;
1054 }
1055
1056
1057 // __str_find_last_not_of
1058 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1059 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1060 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1061 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1062 {
1063 if (__pos < __sz)
1064 ++__pos;
1065 else
1066 __pos = __sz;
1067 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1068 if (_Traits::find(__s, __n, *--__ps) == 0)
1069 return static_cast<_SizeT>(__ps - __p);
1070 return __npos;
1071 }
1072
1073
1074 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1075 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1076 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1077 _CharT __c, _SizeT __pos) _NOEXCEPT
1078 {
1079 if (__pos < __sz)
1080 ++__pos;
1081 else
1082 __pos = __sz;
1083 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1084 if (!_Traits::eq(*--__ps, __c))
1085 return static_cast<_SizeT>(__ps - __p);
1086 return __npos;
1087 }
1088
1089 template<class _Ptr>
1090 inline _LIBCPP_INLINE_VISIBILITY
1091 size_t __do_string_hash(_Ptr __p, _Ptr __e)
1092 {
1093 typedef typename iterator_traits<_Ptr>::value_type value_type;
1094 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
1095 }
1096
1097 template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
1098 struct __quoted_output_proxy
1099 {
1100 _Iter __first;
1101 _Iter __last;
1102 _CharT __delim;
1103 _CharT __escape;
1104
1105 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
1106 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
1107 // This would be a nice place for a string_ref
1108 };
1109
1110 _LIBCPP_END_NAMESPACE_STD
1111
1112 _LIBCPP_POP_MACROS
1113
1114 #endif // _LIBCPP___STRING