blob: 8152660ac19c3adfc59392e13747ae51647b24d8 [file] [log] [blame]
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001// -*- C++ -*-
2//===-------------------------- __string ----------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___STRING
12#define _LIBCPP___STRING
13
14/*
15 string synopsis
16
17namespace std
18{
19
20template <class charT>
21struct char_traits
22{
23 typedef charT char_type;
24 typedef ... int_type;
25 typedef streamoff off_type;
26 typedef streampos pos_type;
27 typedef mbstate_t state_type;
28
Marshall Clow951035b2017-01-12 04:37:14 +000029 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
Marshall Clowdf63a6d2016-07-21 05:31:24 +000030 static constexpr bool eq(char_type c1, char_type c2) noexcept;
31 static constexpr bool lt(char_type c1, char_type c2) noexcept;
32
Marshall Clow951035b2017-01-12 04:37:14 +000033 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);
Marshall Clowdf63a6d2016-07-21 05:31:24 +000037 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);
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
48template <> struct char_traits<char>;
49template <> struct char_traits<wchar_t>;
50
51} // std
52
53*/
54
55#include <__config>
56#include <algorithm> // for search and min
57#include <cstdio> // For EOF.
58#include <memory> // for __murmur2_or_cityhash
59
60#include <__undef_min_max>
61
62#include <__debug>
63
64#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
65#pragma GCC system_header
66#endif
67
68_LIBCPP_BEGIN_NAMESPACE_STD
69
70// char_traits
71
72template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000073struct _LIBCPP_TEMPLATE_VIS char_traits
Marshall Clowdf63a6d2016-07-21 05:31:24 +000074{
75 typedef _CharT char_type;
76 typedef int int_type;
77 typedef streamoff off_type;
78 typedef streampos pos_type;
79 typedef mbstate_t state_type;
80
Marshall Clow951035b2017-01-12 04:37:14 +000081 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
82 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +000083 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
84 {return __c1 == __c2;}
85 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
86 {return __c1 < __c2;}
87
Marshall Clow951035b2017-01-12 04:37:14 +000088 static _LIBCPP_CONSTEXPR_AFTER_CXX14
89 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
90 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
91 size_t length(const char_type* __s);
92 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
93 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
Marshall Clowdf63a6d2016-07-21 05:31:24 +000094 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
95 _LIBCPP_INLINE_VISIBILITY
96 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
97 _LIBCPP_INLINE_VISIBILITY
98 static char_type* assign(char_type* __s, size_t __n, char_type __a);
99
100 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
101 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
102 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
103 {return char_type(__c);}
104 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
105 {return int_type(__c);}
106 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
107 {return __c1 == __c2;}
108 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
109 {return int_type(EOF);}
110};
111
112template <class _CharT>
Marshall Clow951035b2017-01-12 04:37:14 +0000113_LIBCPP_CONSTEXPR_AFTER_CXX14 int
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000114char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
115{
116 for (; __n; --__n, ++__s1, ++__s2)
117 {
118 if (lt(*__s1, *__s2))
119 return -1;
120 if (lt(*__s2, *__s1))
121 return 1;
122 }
123 return 0;
124}
125
126template <class _CharT>
127inline
Marshall Clow951035b2017-01-12 04:37:14 +0000128_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000129char_traits<_CharT>::length(const char_type* __s)
130{
131 size_t __len = 0;
132 for (; !eq(*__s, char_type(0)); ++__s)
133 ++__len;
134 return __len;
135}
136
137template <class _CharT>
138inline
Marshall Clow951035b2017-01-12 04:37:14 +0000139_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000140char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
141{
142 for (; __n; --__n)
143 {
144 if (eq(*__s, __a))
145 return __s;
146 ++__s;
147 }
148 return 0;
149}
150
151template <class _CharT>
152_CharT*
153char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
154{
155 char_type* __r = __s1;
156 if (__s1 < __s2)
157 {
158 for (; __n; --__n, ++__s1, ++__s2)
159 assign(*__s1, *__s2);
160 }
161 else if (__s2 < __s1)
162 {
163 __s1 += __n;
164 __s2 += __n;
165 for (; __n; --__n)
166 assign(*--__s1, *--__s2);
167 }
168 return __r;
169}
170
171template <class _CharT>
172inline
173_CharT*
174char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
175{
176 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
177 char_type* __r = __s1;
178 for (; __n; --__n, ++__s1, ++__s2)
179 assign(*__s1, *__s2);
180 return __r;
181}
182
183template <class _CharT>
184inline
185_CharT*
186char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
187{
188 char_type* __r = __s;
189 for (; __n; --__n, ++__s)
190 assign(*__s, __a);
191 return __r;
192}
193
194// char_traits<char>
195
196template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000197struct _LIBCPP_TEMPLATE_VIS char_traits<char>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000198{
199 typedef char char_type;
200 typedef int int_type;
201 typedef streamoff off_type;
202 typedef streampos pos_type;
203 typedef mbstate_t state_type;
204
Marshall Clow951035b2017-01-12 04:37:14 +0000205 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
206 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000207 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
208 {return __c1 == __c2;}
209 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
210 {return (unsigned char)__c1 < (unsigned char)__c2;}
211
Marshall Clow951035b2017-01-12 04:37:14 +0000212 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
213 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
214 {return __n == 0 ? 0 : __builtin_memcmp(__s1, __s2, __n);}
215 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
216 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
217 static _LIBCPP_CONSTEXPR_AFTER_CXX14
218 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clow36097db2016-07-28 04:52:02 +0000219 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000220 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
Marshall Clow36097db2016-07-28 04:52:02 +0000221 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000222 {
223 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
224 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
225 }
Marshall Clow36097db2016-07-28 04:52:02 +0000226 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000227 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
228
229 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
230 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
231 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
232 {return char_type(__c);}
233 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
234 {return int_type((unsigned char)__c);}
235 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
236 {return __c1 == __c2;}
237 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
238 {return int_type(EOF);}
239};
240
Marshall Clow951035b2017-01-12 04:37:14 +0000241inline _LIBCPP_CONSTEXPR_AFTER_CXX14
242const char*
243char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
244{
245 if (__n == 0)
246 return NULL;
247#if _LIBCPP_STD_VER <= 14
248 return (const char_type*) memchr(__s, to_int_type(__a), __n);
249#else
250 for (; __n; --__n)
251 {
252 if (eq(*__s, __a))
253 return __s;
254 ++__s;
255 }
256 return NULL;
257#endif
258}
259
260
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000261// char_traits<wchar_t>
262
263template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000264struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000265{
266 typedef wchar_t char_type;
267 typedef wint_t int_type;
268 typedef streamoff off_type;
269 typedef streampos pos_type;
270 typedef mbstate_t state_type;
271
Marshall Clow951035b2017-01-12 04:37:14 +0000272 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
273 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000274 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
275 {return __c1 == __c2;}
276 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
277 {return __c1 < __c2;}
278
Marshall Clow951035b2017-01-12 04:37:14 +0000279 static _LIBCPP_CONSTEXPR_AFTER_CXX14
280 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
281 static _LIBCPP_CONSTEXPR_AFTER_CXX14
282 size_t length(const char_type* __s) _NOEXCEPT;
283 static _LIBCPP_CONSTEXPR_AFTER_CXX14
284 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clow36097db2016-07-28 04:52:02 +0000285 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000286 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
Marshall Clow36097db2016-07-28 04:52:02 +0000287 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000288 {
289 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
290 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
291 }
Marshall Clow36097db2016-07-28 04:52:02 +0000292 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000293 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
294
295 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
296 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
297 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
298 {return char_type(__c);}
299 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
300 {return int_type(__c);}
301 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
302 {return __c1 == __c2;}
303 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
304 {return int_type(WEOF);}
305};
306
Marshall Clow951035b2017-01-12 04:37:14 +0000307inline _LIBCPP_CONSTEXPR_AFTER_CXX14
308int
309char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
310{
311 if (__n == 0)
312 return 0;
313#if __has_builtin(__builtin_wmemcmp)
314 return __builtin_wmemcmp(__s1, __s2, __n);
315#elif _LIBCPP_STD_VER <= 14
316 return wmemcmp(__s1, __s2, __n);
317#else
318 for (; __n; --__n, ++__s1, ++__s2)
319 {
320 if (lt(*__s1, *__s2))
321 return -1;
322 if (lt(*__s2, *__s1))
323 return 1;
324 }
325 return 0;
326#endif
327}
328
329inline _LIBCPP_CONSTEXPR_AFTER_CXX14
330size_t
331char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
332{
333#if __has_builtin(__builtin_wcslen)
334 return __builtin_wcslen(__s);
335#elif _LIBCPP_STD_VER <= 14
336 return wcslen(__s);
337#else
338 size_t __len = 0;
339 for (; !eq(*__s, char_type(0)); ++__s)
340 ++__len;
341 return __len;
342#endif
343}
344
345inline _LIBCPP_CONSTEXPR_AFTER_CXX14
346const wchar_t*
347char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
348{
349 if (__n == 0)
350 return NULL;
351#if __has_builtin(__builtin_wmemchr)
352 return __builtin_wmemchr(__s, __a, __n);
353#elif _LIBCPP_STD_VER <= 14
354 return wmemchr(__s, __a, __n);
355#else
356 for (; __n; --__n)
357 {
358 if (eq(*__s, __a))
359 return __s;
360 ++__s;
361 }
362 return NULL;
363#endif
364}
365
366
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000367#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
368
369template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000370struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000371{
372 typedef char16_t char_type;
373 typedef uint_least16_t int_type;
374 typedef streamoff off_type;
375 typedef u16streampos pos_type;
376 typedef mbstate_t state_type;
377
Marshall Clow951035b2017-01-12 04:37:14 +0000378 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
379 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000380 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
381 {return __c1 == __c2;}
382 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
383 {return __c1 < __c2;}
384
Marshall Clow951035b2017-01-12 04:37:14 +0000385 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
386 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
387 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
388 size_t length(const char_type* __s) _NOEXCEPT;
389 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
390 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000391 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000392 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000393 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000394 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000395 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000396 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000397
398 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
399 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
400 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
401 {return char_type(__c);}
402 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
403 {return int_type(__c);}
404 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
405 {return __c1 == __c2;}
406 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
407 {return int_type(0xFFFF);}
408};
409
Marshall Clow951035b2017-01-12 04:37:14 +0000410inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000411int
Marshall Clow36097db2016-07-28 04:52:02 +0000412char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000413{
414 for (; __n; --__n, ++__s1, ++__s2)
415 {
416 if (lt(*__s1, *__s2))
417 return -1;
418 if (lt(*__s2, *__s1))
419 return 1;
420 }
421 return 0;
422}
423
Marshall Clow951035b2017-01-12 04:37:14 +0000424inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000425size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000426char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000427{
428 size_t __len = 0;
429 for (; !eq(*__s, char_type(0)); ++__s)
430 ++__len;
431 return __len;
432}
433
Marshall Clow951035b2017-01-12 04:37:14 +0000434inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000435const char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000436char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000437{
438 for (; __n; --__n)
439 {
440 if (eq(*__s, __a))
441 return __s;
442 ++__s;
443 }
444 return 0;
445}
446
447inline
448char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000449char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000450{
451 char_type* __r = __s1;
452 if (__s1 < __s2)
453 {
454 for (; __n; --__n, ++__s1, ++__s2)
455 assign(*__s1, *__s2);
456 }
457 else if (__s2 < __s1)
458 {
459 __s1 += __n;
460 __s2 += __n;
461 for (; __n; --__n)
462 assign(*--__s1, *--__s2);
463 }
464 return __r;
465}
466
467inline
468char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000469char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000470{
471 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
472 char_type* __r = __s1;
473 for (; __n; --__n, ++__s1, ++__s2)
474 assign(*__s1, *__s2);
475 return __r;
476}
477
478inline
479char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000480char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000481{
482 char_type* __r = __s;
483 for (; __n; --__n, ++__s)
484 assign(*__s, __a);
485 return __r;
486}
487
488template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000489struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000490{
491 typedef char32_t char_type;
492 typedef uint_least32_t int_type;
493 typedef streamoff off_type;
494 typedef u32streampos pos_type;
495 typedef mbstate_t state_type;
496
Marshall Clow951035b2017-01-12 04:37:14 +0000497 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
498 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000499 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
500 {return __c1 == __c2;}
501 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
502 {return __c1 < __c2;}
503
Marshall Clow951035b2017-01-12 04:37:14 +0000504 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
505 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
506 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
507 size_t length(const char_type* __s) _NOEXCEPT;
508 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
509 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000510 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000511 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000512 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000513 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000514 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000515 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000516
517 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
518 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
519 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
520 {return char_type(__c);}
521 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
522 {return int_type(__c);}
523 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
524 {return __c1 == __c2;}
525 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
526 {return int_type(0xFFFFFFFF);}
527};
528
Marshall Clow951035b2017-01-12 04:37:14 +0000529inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000530int
Marshall Clow36097db2016-07-28 04:52:02 +0000531char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000532{
533 for (; __n; --__n, ++__s1, ++__s2)
534 {
535 if (lt(*__s1, *__s2))
536 return -1;
537 if (lt(*__s2, *__s1))
538 return 1;
539 }
540 return 0;
541}
542
Marshall Clow951035b2017-01-12 04:37:14 +0000543inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000544size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000545char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000546{
547 size_t __len = 0;
548 for (; !eq(*__s, char_type(0)); ++__s)
549 ++__len;
550 return __len;
551}
552
Marshall Clow951035b2017-01-12 04:37:14 +0000553inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000554const char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000555char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000556{
557 for (; __n; --__n)
558 {
559 if (eq(*__s, __a))
560 return __s;
561 ++__s;
562 }
563 return 0;
564}
565
566inline
567char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000568char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000569{
570 char_type* __r = __s1;
571 if (__s1 < __s2)
572 {
573 for (; __n; --__n, ++__s1, ++__s2)
574 assign(*__s1, *__s2);
575 }
576 else if (__s2 < __s1)
577 {
578 __s1 += __n;
579 __s2 += __n;
580 for (; __n; --__n)
581 assign(*--__s1, *--__s2);
582 }
583 return __r;
584}
585
586inline
587char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000588char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000589{
590 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
591 char_type* __r = __s1;
592 for (; __n; --__n, ++__s1, ++__s2)
593 assign(*__s1, *__s2);
594 return __r;
595}
596
597inline
598char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000599char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000600{
601 char_type* __r = __s;
602 for (; __n; --__n, ++__s)
603 assign(*__s, __a);
604 return __r;
605}
606
607#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
608
609// helper fns for basic_string and string_view
610
611// __str_find
612template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
613inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
614__str_find(const _CharT *__p, _SizeT __sz,
615 _CharT __c, _SizeT __pos) _NOEXCEPT
616{
617 if (__pos >= __sz)
618 return __npos;
619 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
620 if (__r == 0)
621 return __npos;
622 return static_cast<_SizeT>(__r - __p);
623}
624
Sebastian Pop65115202016-12-30 18:01:36 +0000625template <class _CharT, class _Traits>
626inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
627__search_substring(const _CharT *__first1, const _CharT *__last1,
628 const _CharT *__first2, const _CharT *__last2) {
629 // Take advantage of knowing source and pattern lengths.
630 // Stop short when source is smaller than pattern.
631 const ptrdiff_t __len2 = __last2 - __first2;
632 if (__len2 == 0)
633 return __first1;
634
635 ptrdiff_t __len1 = __last1 - __first1;
636 if (__len1 < __len2)
637 return __last1;
638
639 // First element of __first2 is loop invariant.
640 _CharT __f2 = *__first2;
641 while (true) {
642 __len1 = __last1 - __first1;
643 // Check whether __first1 still has at least __len2 bytes.
644 if (__len1 < __len2)
645 return __last1;
646
647 // Find __f2 the first byte matching in __first1.
648 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
649 if (__first1 == 0)
650 return __last1;
651
652 // It is faster to compare from the first byte of __first1 even if we
653 // already know that it matches the first byte of __first2: this is because
654 // __first2 is most likely aligned, as it is user's "pattern" string, and
655 // __first1 + 1 is most likely not aligned, as the match is in the middle of
656 // the string.
657 if (_Traits::compare(__first1, __first2, __len2) == 0)
658 return __first1;
659
660 ++__first1;
661 }
662}
663
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000664template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
665inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
666__str_find(const _CharT *__p, _SizeT __sz,
667 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
668{
Sebastian Pop65115202016-12-30 18:01:36 +0000669 if (__pos > __sz)
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000670 return __npos;
Sebastian Pop65115202016-12-30 18:01:36 +0000671
672 if (__n == 0) // There is nothing to search, just return __pos.
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000673 return __pos;
Sebastian Pop65115202016-12-30 18:01:36 +0000674
675 const _CharT *__r = __search_substring<_CharT, _Traits>(
676 __p + __pos, __p + __sz, __s, __s + __n);
677
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000678 if (__r == __p + __sz)
679 return __npos;
680 return static_cast<_SizeT>(__r - __p);
681}
682
683
684// __str_rfind
685
686template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
687inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
688__str_rfind(const _CharT *__p, _SizeT __sz,
689 _CharT __c, _SizeT __pos) _NOEXCEPT
690{
691 if (__sz < 1)
692 return __npos;
693 if (__pos < __sz)
694 ++__pos;
695 else
696 __pos = __sz;
697 for (const _CharT* __ps = __p + __pos; __ps != __p;)
698 {
699 if (_Traits::eq(*--__ps, __c))
700 return static_cast<_SizeT>(__ps - __p);
701 }
702 return __npos;
703}
704
705template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
706inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
707__str_rfind(const _CharT *__p, _SizeT __sz,
708 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
709{
710 __pos = _VSTD::min(__pos, __sz);
711 if (__n < __sz - __pos)
712 __pos += __n;
713 else
714 __pos = __sz;
715 const _CharT* __r = _VSTD::__find_end(
716 __p, __p + __pos, __s, __s + __n, _Traits::eq,
717 random_access_iterator_tag(), random_access_iterator_tag());
718 if (__n > 0 && __r == __p + __pos)
719 return __npos;
720 return static_cast<_SizeT>(__r - __p);
721}
722
723// __str_find_first_of
724template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
725inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
726__str_find_first_of(const _CharT *__p, _SizeT __sz,
727 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
728{
729 if (__pos >= __sz || __n == 0)
730 return __npos;
731 const _CharT* __r = _VSTD::__find_first_of_ce
732 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
733 if (__r == __p + __sz)
734 return __npos;
735 return static_cast<_SizeT>(__r - __p);
736}
737
738
739// __str_find_last_of
740template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
741inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
742__str_find_last_of(const _CharT *__p, _SizeT __sz,
743 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
744 {
745 if (__n != 0)
746 {
747 if (__pos < __sz)
748 ++__pos;
749 else
750 __pos = __sz;
751 for (const _CharT* __ps = __p + __pos; __ps != __p;)
752 {
753 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
754 if (__r)
755 return static_cast<_SizeT>(__ps - __p);
756 }
757 }
758 return __npos;
759}
760
761
762// __str_find_first_not_of
763template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
764inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
765__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
766 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
767{
768 if (__pos < __sz)
769 {
770 const _CharT* __pe = __p + __sz;
771 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
772 if (_Traits::find(__s, __n, *__ps) == 0)
773 return static_cast<_SizeT>(__ps - __p);
774 }
775 return __npos;
776}
777
778
779template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
780inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
781__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
782 _CharT __c, _SizeT __pos) _NOEXCEPT
783{
784 if (__pos < __sz)
785 {
786 const _CharT* __pe = __p + __sz;
787 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
788 if (!_Traits::eq(*__ps, __c))
789 return static_cast<_SizeT>(__ps - __p);
790 }
791 return __npos;
792}
793
794
795// __str_find_last_not_of
796template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
797inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
798__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
799 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
800{
801 if (__pos < __sz)
802 ++__pos;
803 else
804 __pos = __sz;
805 for (const _CharT* __ps = __p + __pos; __ps != __p;)
806 if (_Traits::find(__s, __n, *--__ps) == 0)
807 return static_cast<_SizeT>(__ps - __p);
808 return __npos;
809}
810
811
812template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
813inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
814__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
815 _CharT __c, _SizeT __pos) _NOEXCEPT
816{
817 if (__pos < __sz)
818 ++__pos;
819 else
820 __pos = __sz;
821 for (const _CharT* __ps = __p + __pos; __ps != __p;)
822 if (!_Traits::eq(*--__ps, __c))
823 return static_cast<_SizeT>(__ps - __p);
824 return __npos;
825}
826
827template<class _Ptr>
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000828inline _LIBCPP_INLINE_VISIBILITY
829size_t __do_string_hash(_Ptr __p, _Ptr __e)
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000830{
831 typedef typename iterator_traits<_Ptr>::value_type value_type;
832 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
833}
834
835template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
836struct __quoted_output_proxy
837{
838 _Iter __first;
839 _Iter __last;
840 _CharT __delim;
841 _CharT __escape;
842
843 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
844 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
845 // This would be a nice place for a string_ref
846};
847
848_LIBCPP_END_NAMESPACE_STD
849
850#endif // _LIBCPP___STRING