2 //===-------------------------- __string ----------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___STRING
11 #define _LIBCPP___STRING
19 template <class charT>
22 typedef charT char_type;
24 typedef streamoff off_type;
25 typedef streampos pos_type;
26 typedef mbstate_t state_type;
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;
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 static char_type* move(char_type* s1, const char_type* s2, size_t n);
37 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
38 static char_type* assign(char_type* s, size_t n, char_type a);
40 static constexpr int_type not_eof(int_type c) noexcept;
41 static constexpr char_type to_char_type(int_type c) noexcept;
42 static constexpr int_type to_int_type(char_type c) noexcept;
43 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
44 static constexpr int_type eof() noexcept;
47 template <> struct char_traits<char>;
48 template <> struct char_traits<wchar_t>;
49 template <> struct char_traits<char8_t>; // c++20
56 #include <algorithm> // for search and min
57 #include <cstdio> // For EOF.
58 #include <memory> // for __murmur2_or_cityhash
62 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
63 #pragma GCC system_header
67 #include <__undef_macros>
70 _LIBCPP_BEGIN_NAMESPACE_STD
74 template <class _CharT>
75 struct _LIBCPP_TEMPLATE_VIS char_traits
77 typedef _CharT char_type;
79 typedef streamoff off_type;
80 typedef streampos pos_type;
81 typedef mbstate_t state_type;
83 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
84 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
85 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
86 {return __c1 == __c2;}
87 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
90 static _LIBCPP_CONSTEXPR_AFTER_CXX14
91 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
92 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
93 size_t length(const char_type* __s);
94 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
95 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
96 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
97 _LIBCPP_INLINE_VISIBILITY
98 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
99 _LIBCPP_INLINE_VISIBILITY
100 static char_type* assign(char_type* __s, size_t __n, char_type __a);
102 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
103 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
104 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
105 {return char_type(__c);}
106 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
107 {return int_type(__c);}
108 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
109 {return __c1 == __c2;}
110 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
111 {return int_type(EOF);}
114 template <class _CharT>
115 _LIBCPP_CONSTEXPR_AFTER_CXX14 int
116 char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
118 for (; __n; --__n, ++__s1, ++__s2)
120 if (lt(*__s1, *__s2))
122 if (lt(*__s2, *__s1))
128 template <class _CharT>
130 _LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
131 char_traits<_CharT>::length(const char_type* __s)
134 for (; !eq(*__s, char_type(0)); ++__s)
139 template <class _CharT>
141 _LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
142 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
153 template <class _CharT>
155 char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
157 char_type* __r = __s1;
160 for (; __n; --__n, ++__s1, ++__s2)
161 assign(*__s1, *__s2);
163 else if (__s2 < __s1)
168 assign(*--__s1, *--__s2);
173 template <class _CharT>
176 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
178 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
179 char_type* __r = __s1;
180 for (; __n; --__n, ++__s1, ++__s2)
181 assign(*__s1, *__s2);
185 template <class _CharT>
188 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
190 char_type* __r = __s;
191 for (; __n; --__n, ++__s)
199 struct _LIBCPP_TEMPLATE_VIS char_traits<char>
201 typedef char char_type;
202 typedef int int_type;
203 typedef streamoff off_type;
204 typedef streampos pos_type;
205 typedef mbstate_t state_type;
207 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
208 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
209 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
210 {return __c1 == __c2;}
211 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
212 {return (unsigned char)__c1 < (unsigned char)__c2;}
214 static _LIBCPP_CONSTEXPR_AFTER_CXX14
215 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
216 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
217 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
218 static _LIBCPP_CONSTEXPR_AFTER_CXX14
219 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
220 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
221 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
222 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
224 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
225 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
227 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
228 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
230 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
231 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
232 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
233 {return char_type(__c);}
234 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
235 {return int_type((unsigned char)__c);}
236 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
237 {return __c1 == __c2;}
238 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
239 {return int_type(EOF);}
242 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
244 char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
248 #if __has_feature(cxx_constexpr_string_builtins)
249 return __builtin_memcmp(__s1, __s2, __n);
250 #elif _LIBCPP_STD_VER <= 14
251 return memcmp(__s1, __s2, __n);
253 for (; __n; --__n, ++__s1, ++__s2)
255 if (lt(*__s1, *__s2))
257 if (lt(*__s2, *__s1))
264 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
266 char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
270 #if __has_feature(cxx_constexpr_string_builtins)
271 return __builtin_char_memchr(__s, to_int_type(__a), __n);
272 #elif _LIBCPP_STD_VER <= 14
273 return (const char_type*) memchr(__s, to_int_type(__a), __n);
286 // char_traits<wchar_t>
289 struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
291 typedef wchar_t char_type;
292 typedef wint_t int_type;
293 typedef streamoff off_type;
294 typedef streampos pos_type;
295 typedef mbstate_t state_type;
297 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
298 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
299 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 __c1 < __c2;}
304 static _LIBCPP_CONSTEXPR_AFTER_CXX14
305 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
306 static _LIBCPP_CONSTEXPR_AFTER_CXX14
307 size_t length(const char_type* __s) _NOEXCEPT;
308 static _LIBCPP_CONSTEXPR_AFTER_CXX14
309 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
310 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
311 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
312 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
314 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
315 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
317 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
318 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
320 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
321 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
322 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
323 {return char_type(__c);}
324 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
325 {return int_type(__c);}
326 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
327 {return __c1 == __c2;}
328 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
329 {return int_type(WEOF);}
332 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
334 char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
338 #if __has_feature(cxx_constexpr_string_builtins)
339 return __builtin_wmemcmp(__s1, __s2, __n);
340 #elif _LIBCPP_STD_VER <= 14
341 return wmemcmp(__s1, __s2, __n);
343 for (; __n; --__n, ++__s1, ++__s2)
345 if (lt(*__s1, *__s2))
347 if (lt(*__s2, *__s1))
355 template <class _Traits>
356 _LIBCPP_INLINE_VISIBILITY
358 inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
359 #if _LIBCPP_DEBUG_LEVEL >= 1
360 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);
362 return _Traits::length(__s);
366 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
368 char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
370 #if __has_feature(cxx_constexpr_string_builtins)
371 return __builtin_wcslen(__s);
372 #elif _LIBCPP_STD_VER <= 14
376 for (; !eq(*__s, char_type(0)); ++__s)
382 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
384 char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
388 #if __has_feature(cxx_constexpr_string_builtins)
389 return __builtin_wmemchr(__s, __a, __n);
390 #elif _LIBCPP_STD_VER <= 14
391 return wmemchr(__s, __a, __n);
404 #ifndef _LIBCPP_NO_HAS_CHAR8_T
407 struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
409 typedef char8_t char_type;
410 typedef unsigned int int_type;
411 typedef streamoff off_type;
412 typedef u8streampos pos_type;
413 typedef mbstate_t state_type;
415 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
417 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
418 {return __c1 == __c2;}
419 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
420 {return __c1 < __c2;}
423 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
426 size_t length(const char_type* __s) _NOEXCEPT;
428 _LIBCPP_INLINE_VISIBILITY static constexpr
429 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
431 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
432 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
434 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
436 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
437 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
440 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
441 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
443 static inline constexpr int_type not_eof(int_type __c) noexcept
444 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
445 static inline constexpr char_type to_char_type(int_type __c) noexcept
446 {return char_type(__c);}
447 static inline constexpr int_type to_int_type(char_type __c) noexcept
448 {return int_type(__c);}
449 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
450 {return __c1 == __c2;}
451 static inline constexpr int_type eof() noexcept
452 {return int_type(EOF);}
455 // TODO use '__builtin_strlen' if it ever supports char8_t ??
458 char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
461 for (; !eq(*__s, char_type(0)); ++__s)
468 char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
470 #if __has_feature(cxx_constexpr_string_builtins)
471 return __builtin_memcmp(__s1, __s2, __n);
473 for (; __n; --__n, ++__s1, ++__s2)
475 if (lt(*__s1, *__s2))
477 if (lt(*__s2, *__s1))
484 // TODO use '__builtin_char_memchr' if it ever supports char8_t ??
487 char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
498 #endif // #_LIBCPP_NO_HAS_CHAR8_T
500 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
503 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
505 typedef char16_t char_type;
506 typedef uint_least16_t int_type;
507 typedef streamoff off_type;
508 typedef u16streampos pos_type;
509 typedef mbstate_t state_type;
511 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
512 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
513 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
514 {return __c1 == __c2;}
515 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
516 {return __c1 < __c2;}
518 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
519 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
520 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
521 size_t length(const char_type* __s) _NOEXCEPT;
522 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
523 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
524 _LIBCPP_INLINE_VISIBILITY
525 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
526 _LIBCPP_INLINE_VISIBILITY
527 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
528 _LIBCPP_INLINE_VISIBILITY
529 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
531 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
532 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
533 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
534 {return char_type(__c);}
535 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
536 {return int_type(__c);}
537 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
538 {return __c1 == __c2;}
539 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
540 {return int_type(0xFFFF);}
543 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
545 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
547 for (; __n; --__n, ++__s1, ++__s2)
549 if (lt(*__s1, *__s2))
551 if (lt(*__s2, *__s1))
557 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
559 char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
562 for (; !eq(*__s, char_type(0)); ++__s)
567 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
569 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
582 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
584 char_type* __r = __s1;
587 for (; __n; --__n, ++__s1, ++__s2)
588 assign(*__s1, *__s2);
590 else if (__s2 < __s1)
595 assign(*--__s1, *--__s2);
602 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
604 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
605 char_type* __r = __s1;
606 for (; __n; --__n, ++__s1, ++__s2)
607 assign(*__s1, *__s2);
613 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
615 char_type* __r = __s;
616 for (; __n; --__n, ++__s)
622 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
624 typedef char32_t char_type;
625 typedef uint_least32_t int_type;
626 typedef streamoff off_type;
627 typedef u32streampos pos_type;
628 typedef mbstate_t state_type;
630 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
631 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
632 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
633 {return __c1 == __c2;}
634 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
635 {return __c1 < __c2;}
637 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
638 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
639 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
640 size_t length(const char_type* __s) _NOEXCEPT;
641 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
642 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
643 _LIBCPP_INLINE_VISIBILITY
644 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
645 _LIBCPP_INLINE_VISIBILITY
646 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
647 _LIBCPP_INLINE_VISIBILITY
648 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
650 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
651 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
652 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
653 {return char_type(__c);}
654 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
655 {return int_type(__c);}
656 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
657 {return __c1 == __c2;}
658 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
659 {return int_type(0xFFFFFFFF);}
662 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
664 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
666 for (; __n; --__n, ++__s1, ++__s2)
668 if (lt(*__s1, *__s2))
670 if (lt(*__s2, *__s1))
676 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
678 char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
681 for (; !eq(*__s, char_type(0)); ++__s)
686 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
688 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
701 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
703 char_type* __r = __s1;
706 for (; __n; --__n, ++__s1, ++__s2)
707 assign(*__s1, *__s2);
709 else if (__s2 < __s1)
714 assign(*--__s1, *--__s2);
721 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
723 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
724 char_type* __r = __s1;
725 for (; __n; --__n, ++__s1, ++__s2)
726 assign(*__s1, *__s2);
732 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
734 char_type* __r = __s;
735 for (; __n; --__n, ++__s)
740 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
742 // helper fns for basic_string and string_view
745 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
746 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
747 __str_find(const _CharT *__p, _SizeT __sz,
748 _CharT __c, _SizeT __pos) _NOEXCEPT
752 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
755 return static_cast<_SizeT>(__r - __p);
758 template <class _CharT, class _Traits>
759 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
760 __search_substring(const _CharT *__first1, const _CharT *__last1,
761 const _CharT *__first2, const _CharT *__last2) {
762 // Take advantage of knowing source and pattern lengths.
763 // Stop short when source is smaller than pattern.
764 const ptrdiff_t __len2 = __last2 - __first2;
768 ptrdiff_t __len1 = __last1 - __first1;
772 // First element of __first2 is loop invariant.
773 _CharT __f2 = *__first2;
775 __len1 = __last1 - __first1;
776 // Check whether __first1 still has at least __len2 bytes.
780 // Find __f2 the first byte matching in __first1.
781 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
785 // It is faster to compare from the first byte of __first1 even if we
786 // already know that it matches the first byte of __first2: this is because
787 // __first2 is most likely aligned, as it is user's "pattern" string, and
788 // __first1 + 1 is most likely not aligned, as the match is in the middle of
790 if (_Traits::compare(__first1, __first2, __len2) == 0)
797 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
798 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
799 __str_find(const _CharT *__p, _SizeT __sz,
800 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
805 if (__n == 0) // There is nothing to search, just return __pos.
808 const _CharT *__r = __search_substring<_CharT, _Traits>(
809 __p + __pos, __p + __sz, __s, __s + __n);
811 if (__r == __p + __sz)
813 return static_cast<_SizeT>(__r - __p);
819 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
820 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
821 __str_rfind(const _CharT *__p, _SizeT __sz,
822 _CharT __c, _SizeT __pos) _NOEXCEPT
830 for (const _CharT* __ps = __p + __pos; __ps != __p;)
832 if (_Traits::eq(*--__ps, __c))
833 return static_cast<_SizeT>(__ps - __p);
838 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
839 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
840 __str_rfind(const _CharT *__p, _SizeT __sz,
841 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
843 __pos = _VSTD::min(__pos, __sz);
844 if (__n < __sz - __pos)
848 const _CharT* __r = _VSTD::__find_end(
849 __p, __p + __pos, __s, __s + __n, _Traits::eq,
850 random_access_iterator_tag(), random_access_iterator_tag());
851 if (__n > 0 && __r == __p + __pos)
853 return static_cast<_SizeT>(__r - __p);
856 // __str_find_first_of
857 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
858 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
859 __str_find_first_of(const _CharT *__p, _SizeT __sz,
860 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
862 if (__pos >= __sz || __n == 0)
864 const _CharT* __r = _VSTD::__find_first_of_ce
865 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
866 if (__r == __p + __sz)
868 return static_cast<_SizeT>(__r - __p);
872 // __str_find_last_of
873 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
874 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
875 __str_find_last_of(const _CharT *__p, _SizeT __sz,
876 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
884 for (const _CharT* __ps = __p + __pos; __ps != __p;)
886 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
888 return static_cast<_SizeT>(__ps - __p);
895 // __str_find_first_not_of
896 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
897 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
898 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
899 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
903 const _CharT* __pe = __p + __sz;
904 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
905 if (_Traits::find(__s, __n, *__ps) == 0)
906 return static_cast<_SizeT>(__ps - __p);
912 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
913 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
914 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
915 _CharT __c, _SizeT __pos) _NOEXCEPT
919 const _CharT* __pe = __p + __sz;
920 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
921 if (!_Traits::eq(*__ps, __c))
922 return static_cast<_SizeT>(__ps - __p);
928 // __str_find_last_not_of
929 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
930 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
931 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
932 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
938 for (const _CharT* __ps = __p + __pos; __ps != __p;)
939 if (_Traits::find(__s, __n, *--__ps) == 0)
940 return static_cast<_SizeT>(__ps - __p);
945 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
946 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
947 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
948 _CharT __c, _SizeT __pos) _NOEXCEPT
954 for (const _CharT* __ps = __p + __pos; __ps != __p;)
955 if (!_Traits::eq(*--__ps, __c))
956 return static_cast<_SizeT>(__ps - __p);
961 inline _LIBCPP_INLINE_VISIBILITY
962 size_t __do_string_hash(_Ptr __p, _Ptr __e)
964 typedef typename iterator_traits<_Ptr>::value_type value_type;
965 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
968 template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
969 struct __quoted_output_proxy
976 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
977 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
978 // This would be a nice place for a string_ref
981 _LIBCPP_END_NAMESPACE_STD
985 #endif // _LIBCPP___STRING