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))
354 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
356 char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
358 #if __has_feature(cxx_constexpr_string_builtins)
359 return __builtin_wcslen(__s);
360 #elif _LIBCPP_STD_VER <= 14
364 for (; !eq(*__s, char_type(0)); ++__s)
370 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
372 char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
376 #if __has_feature(cxx_constexpr_string_builtins)
377 return __builtin_wmemchr(__s, __a, __n);
378 #elif _LIBCPP_STD_VER <= 14
379 return wmemchr(__s, __a, __n);
392 #ifndef _LIBCPP_NO_HAS_CHAR8_T
395 struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
397 typedef char8_t char_type;
398 typedef unsigned int int_type;
399 typedef streamoff off_type;
400 typedef u8streampos pos_type;
401 typedef mbstate_t state_type;
403 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
405 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
406 {return __c1 == __c2;}
407 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
408 {return __c1 < __c2;}
411 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
414 size_t length(const char_type* __s) _NOEXCEPT;
416 _LIBCPP_INLINE_VISIBILITY static constexpr
417 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
419 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
420 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
422 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
424 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
425 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
428 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
429 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
431 static inline constexpr int_type not_eof(int_type __c) noexcept
432 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
433 static inline constexpr char_type to_char_type(int_type __c) noexcept
434 {return char_type(__c);}
435 static inline constexpr int_type to_int_type(char_type __c) noexcept
436 {return int_type(__c);}
437 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
438 {return __c1 == __c2;}
439 static inline constexpr int_type eof() noexcept
440 {return int_type(EOF);}
443 // TODO use '__builtin_strlen' if it ever supports char8_t ??
446 char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
449 for (; !eq(*__s, char_type(0)); ++__s)
456 char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
458 #if __has_feature(cxx_constexpr_string_builtins)
459 return __builtin_memcmp(__s1, __s2, __n);
461 for (; __n; --__n, ++__s1, ++__s2)
463 if (lt(*__s1, *__s2))
465 if (lt(*__s2, *__s1))
472 // TODO use '__builtin_char_memchr' if it ever supports char8_t ??
475 char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
486 #endif // #_LIBCPP_NO_HAS_CHAR8_T
488 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
491 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
493 typedef char16_t char_type;
494 typedef uint_least16_t int_type;
495 typedef streamoff off_type;
496 typedef u16streampos pos_type;
497 typedef mbstate_t state_type;
499 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
500 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
501 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
502 {return __c1 == __c2;}
503 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
504 {return __c1 < __c2;}
506 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
507 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
508 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
509 size_t length(const char_type* __s) _NOEXCEPT;
510 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
511 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
512 _LIBCPP_INLINE_VISIBILITY
513 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
514 _LIBCPP_INLINE_VISIBILITY
515 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
516 _LIBCPP_INLINE_VISIBILITY
517 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
519 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
520 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
521 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
522 {return char_type(__c);}
523 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
524 {return int_type(__c);}
525 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
526 {return __c1 == __c2;}
527 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
528 {return int_type(0xFFFF);}
531 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
533 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
535 for (; __n; --__n, ++__s1, ++__s2)
537 if (lt(*__s1, *__s2))
539 if (lt(*__s2, *__s1))
545 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
547 char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
550 for (; !eq(*__s, char_type(0)); ++__s)
555 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
557 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
570 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
572 char_type* __r = __s1;
575 for (; __n; --__n, ++__s1, ++__s2)
576 assign(*__s1, *__s2);
578 else if (__s2 < __s1)
583 assign(*--__s1, *--__s2);
590 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
592 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
593 char_type* __r = __s1;
594 for (; __n; --__n, ++__s1, ++__s2)
595 assign(*__s1, *__s2);
601 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
603 char_type* __r = __s;
604 for (; __n; --__n, ++__s)
610 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
612 typedef char32_t char_type;
613 typedef uint_least32_t int_type;
614 typedef streamoff off_type;
615 typedef u32streampos pos_type;
616 typedef mbstate_t state_type;
618 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
619 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
620 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
621 {return __c1 == __c2;}
622 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
623 {return __c1 < __c2;}
625 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
626 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
627 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
628 size_t length(const char_type* __s) _NOEXCEPT;
629 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
630 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
631 _LIBCPP_INLINE_VISIBILITY
632 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
633 _LIBCPP_INLINE_VISIBILITY
634 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
635 _LIBCPP_INLINE_VISIBILITY
636 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
638 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
639 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
640 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
641 {return char_type(__c);}
642 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
643 {return int_type(__c);}
644 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
645 {return __c1 == __c2;}
646 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
647 {return int_type(0xFFFFFFFF);}
650 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
652 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
654 for (; __n; --__n, ++__s1, ++__s2)
656 if (lt(*__s1, *__s2))
658 if (lt(*__s2, *__s1))
664 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
666 char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
669 for (; !eq(*__s, char_type(0)); ++__s)
674 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
676 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
689 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
691 char_type* __r = __s1;
694 for (; __n; --__n, ++__s1, ++__s2)
695 assign(*__s1, *__s2);
697 else if (__s2 < __s1)
702 assign(*--__s1, *--__s2);
709 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
711 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
712 char_type* __r = __s1;
713 for (; __n; --__n, ++__s1, ++__s2)
714 assign(*__s1, *__s2);
720 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
722 char_type* __r = __s;
723 for (; __n; --__n, ++__s)
728 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
730 // helper fns for basic_string and string_view
733 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
734 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
735 __str_find(const _CharT *__p, _SizeT __sz,
736 _CharT __c, _SizeT __pos) _NOEXCEPT
740 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
743 return static_cast<_SizeT>(__r - __p);
746 template <class _CharT, class _Traits>
747 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
748 __search_substring(const _CharT *__first1, const _CharT *__last1,
749 const _CharT *__first2, const _CharT *__last2) {
750 // Take advantage of knowing source and pattern lengths.
751 // Stop short when source is smaller than pattern.
752 const ptrdiff_t __len2 = __last2 - __first2;
756 ptrdiff_t __len1 = __last1 - __first1;
760 // First element of __first2 is loop invariant.
761 _CharT __f2 = *__first2;
763 __len1 = __last1 - __first1;
764 // Check whether __first1 still has at least __len2 bytes.
768 // Find __f2 the first byte matching in __first1.
769 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
773 // It is faster to compare from the first byte of __first1 even if we
774 // already know that it matches the first byte of __first2: this is because
775 // __first2 is most likely aligned, as it is user's "pattern" string, and
776 // __first1 + 1 is most likely not aligned, as the match is in the middle of
778 if (_Traits::compare(__first1, __first2, __len2) == 0)
785 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
786 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
787 __str_find(const _CharT *__p, _SizeT __sz,
788 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
793 if (__n == 0) // There is nothing to search, just return __pos.
796 const _CharT *__r = __search_substring<_CharT, _Traits>(
797 __p + __pos, __p + __sz, __s, __s + __n);
799 if (__r == __p + __sz)
801 return static_cast<_SizeT>(__r - __p);
807 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
808 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
809 __str_rfind(const _CharT *__p, _SizeT __sz,
810 _CharT __c, _SizeT __pos) _NOEXCEPT
818 for (const _CharT* __ps = __p + __pos; __ps != __p;)
820 if (_Traits::eq(*--__ps, __c))
821 return static_cast<_SizeT>(__ps - __p);
826 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
827 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
828 __str_rfind(const _CharT *__p, _SizeT __sz,
829 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
831 __pos = _VSTD::min(__pos, __sz);
832 if (__n < __sz - __pos)
836 const _CharT* __r = _VSTD::__find_end(
837 __p, __p + __pos, __s, __s + __n, _Traits::eq,
838 random_access_iterator_tag(), random_access_iterator_tag());
839 if (__n > 0 && __r == __p + __pos)
841 return static_cast<_SizeT>(__r - __p);
844 // __str_find_first_of
845 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
846 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
847 __str_find_first_of(const _CharT *__p, _SizeT __sz,
848 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
850 if (__pos >= __sz || __n == 0)
852 const _CharT* __r = _VSTD::__find_first_of_ce
853 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
854 if (__r == __p + __sz)
856 return static_cast<_SizeT>(__r - __p);
860 // __str_find_last_of
861 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
862 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
863 __str_find_last_of(const _CharT *__p, _SizeT __sz,
864 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
872 for (const _CharT* __ps = __p + __pos; __ps != __p;)
874 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
876 return static_cast<_SizeT>(__ps - __p);
883 // __str_find_first_not_of
884 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
885 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
886 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
887 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
891 const _CharT* __pe = __p + __sz;
892 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
893 if (_Traits::find(__s, __n, *__ps) == 0)
894 return static_cast<_SizeT>(__ps - __p);
900 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
901 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
902 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
903 _CharT __c, _SizeT __pos) _NOEXCEPT
907 const _CharT* __pe = __p + __sz;
908 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
909 if (!_Traits::eq(*__ps, __c))
910 return static_cast<_SizeT>(__ps - __p);
916 // __str_find_last_not_of
917 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
918 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
919 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
920 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
926 for (const _CharT* __ps = __p + __pos; __ps != __p;)
927 if (_Traits::find(__s, __n, *--__ps) == 0)
928 return static_cast<_SizeT>(__ps - __p);
933 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
934 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
935 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
936 _CharT __c, _SizeT __pos) _NOEXCEPT
942 for (const _CharT* __ps = __p + __pos; __ps != __p;)
943 if (!_Traits::eq(*--__ps, __c))
944 return static_cast<_SizeT>(__ps - __p);
949 inline _LIBCPP_INLINE_VISIBILITY
950 size_t __do_string_hash(_Ptr __p, _Ptr __e)
952 typedef typename iterator_traits<_Ptr>::value_type value_type;
953 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
956 template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
957 struct __quoted_output_proxy
964 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
965 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
966 // This would be a nice place for a string_ref
969 _LIBCPP_END_NAMESPACE_STD
973 #endif // _LIBCPP___STRING