2 //===-------------------------- __string ----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP___STRING
12 #define _LIBCPP___STRING
20 template <class charT>
23 typedef charT char_type;
25 typedef streamoff off_type;
26 typedef streampos pos_type;
27 typedef mbstate_t state_type;
29 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
30 static constexpr bool eq(char_type c1, char_type c2) noexcept;
31 static constexpr bool lt(char_type c1, char_type c2) noexcept;
33 static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
34 static constexpr size_t length(const char_type* s);
35 static constexpr const char_type*
36 find(const char_type* s, size_t n, const char_type& a);
37 static char_type* move(char_type* s1, const char_type* s2, size_t n);
38 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
39 static char_type* assign(char_type* s, size_t n, char_type a);
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;
48 template <> struct char_traits<char>;
49 template <> struct char_traits<wchar_t>;
50 template <> struct char_traits<char8_t>; // c++20
57 #include <algorithm> // for search and min
58 #include <cstdio> // For EOF.
59 #include <memory> // for __murmur2_or_cityhash
63 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64 #pragma GCC system_header
68 #include <__undef_macros>
71 _LIBCPP_BEGIN_NAMESPACE_STD
75 template <class _CharT>
76 struct _LIBCPP_TEMPLATE_VIS char_traits
78 typedef _CharT char_type;
80 typedef streamoff off_type;
81 typedef streampos pos_type;
82 typedef mbstate_t state_type;
84 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
85 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
86 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
87 {return __c1 == __c2;}
88 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
91 static _LIBCPP_CONSTEXPR_AFTER_CXX14
92 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
93 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
94 size_t length(const char_type* __s);
95 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
96 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
97 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
98 _LIBCPP_INLINE_VISIBILITY
99 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
100 _LIBCPP_INLINE_VISIBILITY
101 static char_type* assign(char_type* __s, size_t __n, char_type __a);
103 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
104 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
105 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
106 {return char_type(__c);}
107 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
108 {return int_type(__c);}
109 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
110 {return __c1 == __c2;}
111 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
112 {return int_type(EOF);}
115 template <class _CharT>
116 _LIBCPP_CONSTEXPR_AFTER_CXX14 int
117 char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
119 for (; __n; --__n, ++__s1, ++__s2)
121 if (lt(*__s1, *__s2))
123 if (lt(*__s2, *__s1))
129 template <class _CharT>
131 _LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
132 char_traits<_CharT>::length(const char_type* __s)
135 for (; !eq(*__s, char_type(0)); ++__s)
140 template <class _CharT>
142 _LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
143 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
154 template <class _CharT>
156 char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
158 char_type* __r = __s1;
161 for (; __n; --__n, ++__s1, ++__s2)
162 assign(*__s1, *__s2);
164 else if (__s2 < __s1)
169 assign(*--__s1, *--__s2);
174 template <class _CharT>
177 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
179 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
180 char_type* __r = __s1;
181 for (; __n; --__n, ++__s1, ++__s2)
182 assign(*__s1, *__s2);
186 template <class _CharT>
189 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
191 char_type* __r = __s;
192 for (; __n; --__n, ++__s)
200 struct _LIBCPP_TEMPLATE_VIS char_traits<char>
202 typedef char char_type;
203 typedef int int_type;
204 typedef streamoff off_type;
205 typedef streampos pos_type;
206 typedef mbstate_t state_type;
208 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
209 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
210 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
211 {return __c1 == __c2;}
212 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
213 {return (unsigned char)__c1 < (unsigned char)__c2;}
215 static _LIBCPP_CONSTEXPR_AFTER_CXX14
216 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
217 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
218 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
219 static _LIBCPP_CONSTEXPR_AFTER_CXX14
220 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
221 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
222 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
223 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
225 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
226 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
228 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
229 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
231 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
232 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
233 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
234 {return char_type(__c);}
235 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
236 {return int_type((unsigned char)__c);}
237 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
238 {return __c1 == __c2;}
239 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
240 {return int_type(EOF);}
243 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
245 char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
249 #if __has_feature(cxx_constexpr_string_builtins)
250 return __builtin_memcmp(__s1, __s2, __n);
251 #elif _LIBCPP_STD_VER <= 14
252 return memcmp(__s1, __s2, __n);
254 for (; __n; --__n, ++__s1, ++__s2)
256 if (lt(*__s1, *__s2))
258 if (lt(*__s2, *__s1))
265 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
267 char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
271 #if __has_feature(cxx_constexpr_string_builtins)
272 return __builtin_char_memchr(__s, to_int_type(__a), __n);
273 #elif _LIBCPP_STD_VER <= 14
274 return (const char_type*) memchr(__s, to_int_type(__a), __n);
287 // char_traits<wchar_t>
290 struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
292 typedef wchar_t char_type;
293 typedef wint_t int_type;
294 typedef streamoff off_type;
295 typedef streampos pos_type;
296 typedef mbstate_t state_type;
298 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
299 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
300 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
301 {return __c1 == __c2;}
302 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
303 {return __c1 < __c2;}
305 static _LIBCPP_CONSTEXPR_AFTER_CXX14
306 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
307 static _LIBCPP_CONSTEXPR_AFTER_CXX14
308 size_t length(const char_type* __s) _NOEXCEPT;
309 static _LIBCPP_CONSTEXPR_AFTER_CXX14
310 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
311 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
312 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
313 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
315 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
316 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
318 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
319 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
321 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
322 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
323 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
324 {return char_type(__c);}
325 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
326 {return int_type(__c);}
327 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
328 {return __c1 == __c2;}
329 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
330 {return int_type(WEOF);}
333 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
335 char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
339 #if __has_feature(cxx_constexpr_string_builtins)
340 return __builtin_wmemcmp(__s1, __s2, __n);
341 #elif _LIBCPP_STD_VER <= 14
342 return wmemcmp(__s1, __s2, __n);
344 for (; __n; --__n, ++__s1, ++__s2)
346 if (lt(*__s1, *__s2))
348 if (lt(*__s2, *__s1))
355 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
357 char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
359 #if __has_feature(cxx_constexpr_string_builtins)
360 return __builtin_wcslen(__s);
361 #elif _LIBCPP_STD_VER <= 14
365 for (; !eq(*__s, char_type(0)); ++__s)
371 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
373 char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
377 #if __has_feature(cxx_constexpr_string_builtins)
378 return __builtin_wmemchr(__s, __a, __n);
379 #elif _LIBCPP_STD_VER <= 14
380 return wmemchr(__s, __a, __n);
393 #ifndef _LIBCPP_NO_HAS_CHAR8_T
396 struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
398 typedef char8_t char_type;
399 typedef unsigned int int_type;
400 typedef streamoff off_type;
401 typedef u8streampos pos_type;
402 typedef mbstate_t state_type;
404 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
406 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
407 {return __c1 == __c2;}
408 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
409 {return __c1 < __c2;}
412 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
415 size_t length(const char_type* __s) _NOEXCEPT;
417 _LIBCPP_INLINE_VISIBILITY static constexpr
418 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
420 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
421 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
423 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
425 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
426 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
429 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
430 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
432 static inline constexpr int_type not_eof(int_type __c) noexcept
433 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
434 static inline constexpr char_type to_char_type(int_type __c) noexcept
435 {return char_type(__c);}
436 static inline constexpr int_type to_int_type(char_type __c) noexcept
437 {return int_type(__c);}
438 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
439 {return __c1 == __c2;}
440 static inline constexpr int_type eof() noexcept
441 {return int_type(EOF);}
444 // TODO use '__builtin_strlen' if it ever supports char8_t ??
447 char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
450 for (; !eq(*__s, char_type(0)); ++__s)
457 char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
459 #if __has_feature(cxx_constexpr_string_builtins)
460 return __builtin_memcmp(__s1, __s2, __n);
462 for (; __n; --__n, ++__s1, ++__s2)
464 if (lt(*__s1, *__s2))
466 if (lt(*__s2, *__s1))
473 // TODO use '__builtin_char_memchr' if it ever supports char8_t ??
476 char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
487 #endif // #_LIBCPP_NO_HAS_CHAR8_T
489 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
492 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
494 typedef char16_t char_type;
495 typedef uint_least16_t int_type;
496 typedef streamoff off_type;
497 typedef u16streampos pos_type;
498 typedef mbstate_t state_type;
500 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
501 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
502 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
503 {return __c1 == __c2;}
504 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
505 {return __c1 < __c2;}
507 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
508 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
509 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
510 size_t length(const char_type* __s) _NOEXCEPT;
511 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
512 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
513 _LIBCPP_INLINE_VISIBILITY
514 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
515 _LIBCPP_INLINE_VISIBILITY
516 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
517 _LIBCPP_INLINE_VISIBILITY
518 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
520 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
521 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
522 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
523 {return char_type(__c);}
524 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
525 {return int_type(__c);}
526 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
527 {return __c1 == __c2;}
528 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
529 {return int_type(0xFFFF);}
532 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
534 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
536 for (; __n; --__n, ++__s1, ++__s2)
538 if (lt(*__s1, *__s2))
540 if (lt(*__s2, *__s1))
546 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
548 char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
551 for (; !eq(*__s, char_type(0)); ++__s)
556 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
558 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
571 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
573 char_type* __r = __s1;
576 for (; __n; --__n, ++__s1, ++__s2)
577 assign(*__s1, *__s2);
579 else if (__s2 < __s1)
584 assign(*--__s1, *--__s2);
591 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
593 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
594 char_type* __r = __s1;
595 for (; __n; --__n, ++__s1, ++__s2)
596 assign(*__s1, *__s2);
602 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
604 char_type* __r = __s;
605 for (; __n; --__n, ++__s)
611 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
613 typedef char32_t char_type;
614 typedef uint_least32_t int_type;
615 typedef streamoff off_type;
616 typedef u32streampos pos_type;
617 typedef mbstate_t state_type;
619 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
620 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
621 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
622 {return __c1 == __c2;}
623 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
624 {return __c1 < __c2;}
626 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
627 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
628 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
629 size_t length(const char_type* __s) _NOEXCEPT;
630 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
631 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
632 _LIBCPP_INLINE_VISIBILITY
633 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
634 _LIBCPP_INLINE_VISIBILITY
635 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
636 _LIBCPP_INLINE_VISIBILITY
637 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
639 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
640 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
641 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
642 {return char_type(__c);}
643 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
644 {return int_type(__c);}
645 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
646 {return __c1 == __c2;}
647 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
648 {return int_type(0xFFFFFFFF);}
651 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
653 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
655 for (; __n; --__n, ++__s1, ++__s2)
657 if (lt(*__s1, *__s2))
659 if (lt(*__s2, *__s1))
665 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
667 char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
670 for (; !eq(*__s, char_type(0)); ++__s)
675 inline _LIBCPP_CONSTEXPR_AFTER_CXX14
677 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
690 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
692 char_type* __r = __s1;
695 for (; __n; --__n, ++__s1, ++__s2)
696 assign(*__s1, *__s2);
698 else if (__s2 < __s1)
703 assign(*--__s1, *--__s2);
710 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
712 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
713 char_type* __r = __s1;
714 for (; __n; --__n, ++__s1, ++__s2)
715 assign(*__s1, *__s2);
721 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
723 char_type* __r = __s;
724 for (; __n; --__n, ++__s)
729 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
731 // helper fns for basic_string and string_view
734 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
735 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
736 __str_find(const _CharT *__p, _SizeT __sz,
737 _CharT __c, _SizeT __pos) _NOEXCEPT
741 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
744 return static_cast<_SizeT>(__r - __p);
747 template <class _CharT, class _Traits>
748 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
749 __search_substring(const _CharT *__first1, const _CharT *__last1,
750 const _CharT *__first2, const _CharT *__last2) {
751 // Take advantage of knowing source and pattern lengths.
752 // Stop short when source is smaller than pattern.
753 const ptrdiff_t __len2 = __last2 - __first2;
757 ptrdiff_t __len1 = __last1 - __first1;
761 // First element of __first2 is loop invariant.
762 _CharT __f2 = *__first2;
764 __len1 = __last1 - __first1;
765 // Check whether __first1 still has at least __len2 bytes.
769 // Find __f2 the first byte matching in __first1.
770 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
774 // It is faster to compare from the first byte of __first1 even if we
775 // already know that it matches the first byte of __first2: this is because
776 // __first2 is most likely aligned, as it is user's "pattern" string, and
777 // __first1 + 1 is most likely not aligned, as the match is in the middle of
779 if (_Traits::compare(__first1, __first2, __len2) == 0)
786 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
787 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
788 __str_find(const _CharT *__p, _SizeT __sz,
789 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
794 if (__n == 0) // There is nothing to search, just return __pos.
797 const _CharT *__r = __search_substring<_CharT, _Traits>(
798 __p + __pos, __p + __sz, __s, __s + __n);
800 if (__r == __p + __sz)
802 return static_cast<_SizeT>(__r - __p);
808 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
809 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
810 __str_rfind(const _CharT *__p, _SizeT __sz,
811 _CharT __c, _SizeT __pos) _NOEXCEPT
819 for (const _CharT* __ps = __p + __pos; __ps != __p;)
821 if (_Traits::eq(*--__ps, __c))
822 return static_cast<_SizeT>(__ps - __p);
827 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
828 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
829 __str_rfind(const _CharT *__p, _SizeT __sz,
830 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
832 __pos = _VSTD::min(__pos, __sz);
833 if (__n < __sz - __pos)
837 const _CharT* __r = _VSTD::__find_end(
838 __p, __p + __pos, __s, __s + __n, _Traits::eq,
839 random_access_iterator_tag(), random_access_iterator_tag());
840 if (__n > 0 && __r == __p + __pos)
842 return static_cast<_SizeT>(__r - __p);
845 // __str_find_first_of
846 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
847 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
848 __str_find_first_of(const _CharT *__p, _SizeT __sz,
849 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
851 if (__pos >= __sz || __n == 0)
853 const _CharT* __r = _VSTD::__find_first_of_ce
854 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
855 if (__r == __p + __sz)
857 return static_cast<_SizeT>(__r - __p);
861 // __str_find_last_of
862 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
863 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
864 __str_find_last_of(const _CharT *__p, _SizeT __sz,
865 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
873 for (const _CharT* __ps = __p + __pos; __ps != __p;)
875 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
877 return static_cast<_SizeT>(__ps - __p);
884 // __str_find_first_not_of
885 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
886 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
887 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
888 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
892 const _CharT* __pe = __p + __sz;
893 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
894 if (_Traits::find(__s, __n, *__ps) == 0)
895 return static_cast<_SizeT>(__ps - __p);
901 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
902 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
903 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
904 _CharT __c, _SizeT __pos) _NOEXCEPT
908 const _CharT* __pe = __p + __sz;
909 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
910 if (!_Traits::eq(*__ps, __c))
911 return static_cast<_SizeT>(__ps - __p);
917 // __str_find_last_not_of
918 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
919 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
920 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
921 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
927 for (const _CharT* __ps = __p + __pos; __ps != __p;)
928 if (_Traits::find(__s, __n, *--__ps) == 0)
929 return static_cast<_SizeT>(__ps - __p);
934 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
935 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
936 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
937 _CharT __c, _SizeT __pos) _NOEXCEPT
943 for (const _CharT* __ps = __p + __pos; __ps != __p;)
944 if (!_Traits::eq(*--__ps, __c))
945 return static_cast<_SizeT>(__ps - __p);
950 inline _LIBCPP_INLINE_VISIBILITY
951 size_t __do_string_hash(_Ptr __p, _Ptr __e)
953 typedef typename iterator_traits<_Ptr>::value_type value_type;
954 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
957 template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
958 struct __quoted_output_proxy
965 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
966 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
967 // This would be a nice place for a string_ref
970 _LIBCPP_END_NAMESPACE_STD
974 #endif // _LIBCPP___STRING