blob: 1ddeec7149fb654effffa0324f47b00bd49b99a4 [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>;
Marshall Clow8732fed2018-12-11 04:35:44 +000050template <> struct char_traits<char8_t>; // c++20
Marshall Clowdf63a6d2016-07-21 05:31:24 +000051
52} // std
53
54*/
55
56#include <__config>
57#include <algorithm> // for search and min
58#include <cstdio> // For EOF.
59#include <memory> // for __murmur2_or_cityhash
60
Marshall Clowdf63a6d2016-07-21 05:31:24 +000061#include <__debug>
62
63#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64#pragma GCC system_header
65#endif
66
Eric Fiselierf4433a32017-05-31 22:07:49 +000067_LIBCPP_PUSH_MACROS
68#include <__undef_macros>
69
70
Marshall Clowdf63a6d2016-07-21 05:31:24 +000071_LIBCPP_BEGIN_NAMESPACE_STD
72
73// char_traits
74
75template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000076struct _LIBCPP_TEMPLATE_VIS char_traits
Marshall Clowdf63a6d2016-07-21 05:31:24 +000077{
78 typedef _CharT char_type;
79 typedef int int_type;
80 typedef streamoff off_type;
81 typedef streampos pos_type;
82 typedef mbstate_t state_type;
83
Marshall Clow951035b2017-01-12 04:37:14 +000084 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
85 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +000086 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
89 {return __c1 < __c2;}
90
Marshall Clow951035b2017-01-12 04:37:14 +000091 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);
Marshall Clowdf63a6d2016-07-21 05:31:24 +000097 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);
102
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);}
113};
114
115template <class _CharT>
Marshall Clow951035b2017-01-12 04:37:14 +0000116_LIBCPP_CONSTEXPR_AFTER_CXX14 int
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000117char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
118{
119 for (; __n; --__n, ++__s1, ++__s2)
120 {
121 if (lt(*__s1, *__s2))
122 return -1;
123 if (lt(*__s2, *__s1))
124 return 1;
125 }
126 return 0;
127}
128
129template <class _CharT>
130inline
Marshall Clow951035b2017-01-12 04:37:14 +0000131_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000132char_traits<_CharT>::length(const char_type* __s)
133{
134 size_t __len = 0;
135 for (; !eq(*__s, char_type(0)); ++__s)
136 ++__len;
137 return __len;
138}
139
140template <class _CharT>
141inline
Marshall Clow951035b2017-01-12 04:37:14 +0000142_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000143char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
144{
145 for (; __n; --__n)
146 {
147 if (eq(*__s, __a))
148 return __s;
149 ++__s;
150 }
151 return 0;
152}
153
154template <class _CharT>
155_CharT*
156char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
157{
158 char_type* __r = __s1;
159 if (__s1 < __s2)
160 {
161 for (; __n; --__n, ++__s1, ++__s2)
162 assign(*__s1, *__s2);
163 }
164 else if (__s2 < __s1)
165 {
166 __s1 += __n;
167 __s2 += __n;
168 for (; __n; --__n)
169 assign(*--__s1, *--__s2);
170 }
171 return __r;
172}
173
174template <class _CharT>
175inline
176_CharT*
177char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
178{
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);
183 return __r;
184}
185
186template <class _CharT>
187inline
188_CharT*
189char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
190{
191 char_type* __r = __s;
192 for (; __n; --__n, ++__s)
193 assign(*__s, __a);
194 return __r;
195}
196
197// char_traits<char>
198
199template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000200struct _LIBCPP_TEMPLATE_VIS char_traits<char>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000201{
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;
207
Marshall Clow951035b2017-01-12 04:37:14 +0000208 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
209 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000210 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;}
214
Marshall Clowaa32f162017-01-12 05:40:58 +0000215 static _LIBCPP_CONSTEXPR_AFTER_CXX14
216 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow951035b2017-01-12 04:37:14 +0000217 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;
Marshall Clow36097db2016-07-28 04:52:02 +0000221 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000222 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
Marshall Clow36097db2016-07-28 04:52:02 +0000223 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000224 {
225 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
226 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
227 }
Marshall Clow36097db2016-07-28 04:52:02 +0000228 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000229 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
230
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);}
241};
242
Marshall Clow951035b2017-01-12 04:37:14 +0000243inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowaa32f162017-01-12 05:40:58 +0000244int
245char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
246{
247 if (__n == 0)
248 return 0;
Marshall Clowb344c362017-01-26 06:58:29 +0000249#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clowaa32f162017-01-12 05:40:58 +0000250 return __builtin_memcmp(__s1, __s2, __n);
251#elif _LIBCPP_STD_VER <= 14
252 return memcmp(__s1, __s2, __n);
253#else
254 for (; __n; --__n, ++__s1, ++__s2)
255 {
256 if (lt(*__s1, *__s2))
257 return -1;
258 if (lt(*__s2, *__s1))
259 return 1;
260 }
261 return 0;
262#endif
263}
264
265inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow951035b2017-01-12 04:37:14 +0000266const char*
267char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
268{
269 if (__n == 0)
Marshall Clow32043ac2018-02-06 18:58:05 +0000270 return nullptr;
Marshall Clowb344c362017-01-26 06:58:29 +0000271#if __has_feature(cxx_constexpr_string_builtins)
272 return __builtin_char_memchr(__s, to_int_type(__a), __n);
273#elif _LIBCPP_STD_VER <= 14
Marshall Clow951035b2017-01-12 04:37:14 +0000274 return (const char_type*) memchr(__s, to_int_type(__a), __n);
275#else
276 for (; __n; --__n)
277 {
278 if (eq(*__s, __a))
279 return __s;
280 ++__s;
281 }
Marshall Clow32043ac2018-02-06 18:58:05 +0000282 return nullptr;
Marshall Clow951035b2017-01-12 04:37:14 +0000283#endif
284}
285
286
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000287// char_traits<wchar_t>
288
289template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000290struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000291{
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;
297
Marshall Clow951035b2017-01-12 04:37:14 +0000298 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
299 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000300 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;}
304
Marshall Clow951035b2017-01-12 04:37:14 +0000305 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;
Marshall Clow36097db2016-07-28 04:52:02 +0000311 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000312 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
Marshall Clow36097db2016-07-28 04:52:02 +0000313 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000314 {
315 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
316 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
317 }
Marshall Clow36097db2016-07-28 04:52:02 +0000318 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000319 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
320
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);}
331};
332
Marshall Clow951035b2017-01-12 04:37:14 +0000333inline _LIBCPP_CONSTEXPR_AFTER_CXX14
334int
335char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
336{
337 if (__n == 0)
338 return 0;
Marshall Clowb344c362017-01-26 06:58:29 +0000339#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow951035b2017-01-12 04:37:14 +0000340 return __builtin_wmemcmp(__s1, __s2, __n);
341#elif _LIBCPP_STD_VER <= 14
342 return wmemcmp(__s1, __s2, __n);
343#else
344 for (; __n; --__n, ++__s1, ++__s2)
345 {
346 if (lt(*__s1, *__s2))
347 return -1;
348 if (lt(*__s2, *__s1))
349 return 1;
350 }
351 return 0;
352#endif
353}
354
355inline _LIBCPP_CONSTEXPR_AFTER_CXX14
356size_t
357char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
358{
Marshall Clowb344c362017-01-26 06:58:29 +0000359#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow951035b2017-01-12 04:37:14 +0000360 return __builtin_wcslen(__s);
361#elif _LIBCPP_STD_VER <= 14
362 return wcslen(__s);
363#else
364 size_t __len = 0;
365 for (; !eq(*__s, char_type(0)); ++__s)
366 ++__len;
367 return __len;
368#endif
369}
370
371inline _LIBCPP_CONSTEXPR_AFTER_CXX14
372const wchar_t*
373char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
374{
375 if (__n == 0)
Marshall Clow32043ac2018-02-06 18:58:05 +0000376 return nullptr;
Marshall Clowb344c362017-01-26 06:58:29 +0000377#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow32043ac2018-02-06 18:58:05 +0000378 return __builtin_wmemchr(__s, __a, __n);
Marshall Clow951035b2017-01-12 04:37:14 +0000379#elif _LIBCPP_STD_VER <= 14
380 return wmemchr(__s, __a, __n);
381#else
382 for (; __n; --__n)
383 {
384 if (eq(*__s, __a))
385 return __s;
386 ++__s;
387 }
Marshall Clow32043ac2018-02-06 18:58:05 +0000388 return nullptr;
Marshall Clow951035b2017-01-12 04:37:14 +0000389#endif
390}
391
392
Marshall Clow8732fed2018-12-11 04:35:44 +0000393#ifndef _LIBCPP_NO_HAS_CHAR8_T
394
395template <>
396struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
397{
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;
403
404 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
405 {__c1 = __c2;}
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;}
410
411 static constexpr
412 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
413
414 static constexpr
415 size_t length(const char_type* __s) _NOEXCEPT;
416
417 _LIBCPP_INLINE_VISIBILITY static constexpr
418 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
419
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);}
422
423 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
424 {
425 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
426 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
427 }
428
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);}
431
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);}
442};
443
444// TODO use '__builtin_strlen' if it ever supports char8_t ??
445inline constexpr
446size_t
447char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
448{
449 size_t __len = 0;
450 for (; !eq(*__s, char_type(0)); ++__s)
451 ++__len;
452 return __len;
453}
454
455inline constexpr
456int
457char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
458{
459#if __has_feature(cxx_constexpr_string_builtins)
460 return __builtin_memcmp(__s1, __s2, __n);
461#else
462 for (; __n; --__n, ++__s1, ++__s2)
463 {
464 if (lt(*__s1, *__s2))
465 return -1;
466 if (lt(*__s2, *__s1))
467 return 1;
468 }
469 return 0;
470#endif
471}
472
473// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
474inline constexpr
475const char8_t*
476char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
477{
478 for (; __n; --__n)
479 {
480 if (eq(*__s, __a))
481 return __s;
482 ++__s;
483 }
484 return 0;
485}
486
487#endif // #_LIBCPP_NO_HAS_CHAR8_T
488
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000489#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
490
491template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000492struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000493{
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;
499
Marshall Clow951035b2017-01-12 04:37:14 +0000500 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
501 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000502 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;}
506
Marshall Clow951035b2017-01-12 04:37:14 +0000507 _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;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000513 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000514 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000515 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000516 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000517 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000518 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000519
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);}
530};
531
Marshall Clow951035b2017-01-12 04:37:14 +0000532inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000533int
Marshall Clow36097db2016-07-28 04:52:02 +0000534char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000535{
536 for (; __n; --__n, ++__s1, ++__s2)
537 {
538 if (lt(*__s1, *__s2))
539 return -1;
540 if (lt(*__s2, *__s1))
541 return 1;
542 }
543 return 0;
544}
545
Marshall Clow951035b2017-01-12 04:37:14 +0000546inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000547size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000548char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000549{
550 size_t __len = 0;
551 for (; !eq(*__s, char_type(0)); ++__s)
552 ++__len;
553 return __len;
554}
555
Marshall Clow951035b2017-01-12 04:37:14 +0000556inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000557const char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000558char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000559{
560 for (; __n; --__n)
561 {
562 if (eq(*__s, __a))
563 return __s;
564 ++__s;
565 }
566 return 0;
567}
568
569inline
570char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000571char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000572{
573 char_type* __r = __s1;
574 if (__s1 < __s2)
575 {
576 for (; __n; --__n, ++__s1, ++__s2)
577 assign(*__s1, *__s2);
578 }
579 else if (__s2 < __s1)
580 {
581 __s1 += __n;
582 __s2 += __n;
583 for (; __n; --__n)
584 assign(*--__s1, *--__s2);
585 }
586 return __r;
587}
588
589inline
590char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000591char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000592{
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);
597 return __r;
598}
599
600inline
601char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000602char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000603{
604 char_type* __r = __s;
605 for (; __n; --__n, ++__s)
606 assign(*__s, __a);
607 return __r;
608}
609
610template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000611struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000612{
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;
618
Marshall Clow951035b2017-01-12 04:37:14 +0000619 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
620 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000621 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;}
625
Marshall Clow951035b2017-01-12 04:37:14 +0000626 _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;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000632 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000633 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000634 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000635 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000636 _LIBCPP_INLINE_VISIBILITY
Marshall Clow36097db2016-07-28 04:52:02 +0000637 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000638
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);}
649};
650
Marshall Clow951035b2017-01-12 04:37:14 +0000651inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000652int
Marshall Clow36097db2016-07-28 04:52:02 +0000653char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000654{
655 for (; __n; --__n, ++__s1, ++__s2)
656 {
657 if (lt(*__s1, *__s2))
658 return -1;
659 if (lt(*__s2, *__s1))
660 return 1;
661 }
662 return 0;
663}
664
Marshall Clow951035b2017-01-12 04:37:14 +0000665inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000666size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000667char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000668{
669 size_t __len = 0;
670 for (; !eq(*__s, char_type(0)); ++__s)
671 ++__len;
672 return __len;
673}
674
Marshall Clow951035b2017-01-12 04:37:14 +0000675inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000676const char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000677char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000678{
679 for (; __n; --__n)
680 {
681 if (eq(*__s, __a))
682 return __s;
683 ++__s;
684 }
685 return 0;
686}
687
688inline
689char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000690char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000691{
692 char_type* __r = __s1;
693 if (__s1 < __s2)
694 {
695 for (; __n; --__n, ++__s1, ++__s2)
696 assign(*__s1, *__s2);
697 }
698 else if (__s2 < __s1)
699 {
700 __s1 += __n;
701 __s2 += __n;
702 for (; __n; --__n)
703 assign(*--__s1, *--__s2);
704 }
705 return __r;
706}
707
708inline
709char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000710char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000711{
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);
716 return __r;
717}
718
719inline
720char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000721char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000722{
723 char_type* __r = __s;
724 for (; __n; --__n, ++__s)
725 assign(*__s, __a);
726 return __r;
727}
728
729#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
730
731// helper fns for basic_string and string_view
732
733// __str_find
734template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
735inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
736__str_find(const _CharT *__p, _SizeT __sz,
737 _CharT __c, _SizeT __pos) _NOEXCEPT
738{
739 if (__pos >= __sz)
740 return __npos;
741 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
742 if (__r == 0)
743 return __npos;
744 return static_cast<_SizeT>(__r - __p);
745}
746
Sebastian Pop65115202016-12-30 18:01:36 +0000747template <class _CharT, class _Traits>
748inline _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;
754 if (__len2 == 0)
755 return __first1;
756
757 ptrdiff_t __len1 = __last1 - __first1;
758 if (__len1 < __len2)
759 return __last1;
760
761 // First element of __first2 is loop invariant.
762 _CharT __f2 = *__first2;
763 while (true) {
764 __len1 = __last1 - __first1;
765 // Check whether __first1 still has at least __len2 bytes.
766 if (__len1 < __len2)
767 return __last1;
768
769 // Find __f2 the first byte matching in __first1.
770 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
771 if (__first1 == 0)
772 return __last1;
773
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
778 // the string.
779 if (_Traits::compare(__first1, __first2, __len2) == 0)
780 return __first1;
781
782 ++__first1;
783 }
784}
785
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000786template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
787inline _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
790{
Sebastian Pop65115202016-12-30 18:01:36 +0000791 if (__pos > __sz)
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000792 return __npos;
Sebastian Pop65115202016-12-30 18:01:36 +0000793
794 if (__n == 0) // There is nothing to search, just return __pos.
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000795 return __pos;
Sebastian Pop65115202016-12-30 18:01:36 +0000796
797 const _CharT *__r = __search_substring<_CharT, _Traits>(
798 __p + __pos, __p + __sz, __s, __s + __n);
799
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000800 if (__r == __p + __sz)
801 return __npos;
802 return static_cast<_SizeT>(__r - __p);
803}
804
805
806// __str_rfind
807
808template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
809inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
810__str_rfind(const _CharT *__p, _SizeT __sz,
811 _CharT __c, _SizeT __pos) _NOEXCEPT
812{
813 if (__sz < 1)
814 return __npos;
815 if (__pos < __sz)
816 ++__pos;
817 else
818 __pos = __sz;
819 for (const _CharT* __ps = __p + __pos; __ps != __p;)
820 {
821 if (_Traits::eq(*--__ps, __c))
822 return static_cast<_SizeT>(__ps - __p);
823 }
824 return __npos;
825}
826
827template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
828inline _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
831{
832 __pos = _VSTD::min(__pos, __sz);
833 if (__n < __sz - __pos)
834 __pos += __n;
835 else
836 __pos = __sz;
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)
841 return __npos;
842 return static_cast<_SizeT>(__r - __p);
843}
844
845// __str_find_first_of
846template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
847inline _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
850{
851 if (__pos >= __sz || __n == 0)
852 return __npos;
853 const _CharT* __r = _VSTD::__find_first_of_ce
854 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
855 if (__r == __p + __sz)
856 return __npos;
857 return static_cast<_SizeT>(__r - __p);
858}
859
860
861// __str_find_last_of
862template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
863inline _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
866 {
867 if (__n != 0)
868 {
869 if (__pos < __sz)
870 ++__pos;
871 else
872 __pos = __sz;
873 for (const _CharT* __ps = __p + __pos; __ps != __p;)
874 {
875 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
876 if (__r)
877 return static_cast<_SizeT>(__ps - __p);
878 }
879 }
880 return __npos;
881}
882
883
884// __str_find_first_not_of
885template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
886inline _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
889{
890 if (__pos < __sz)
891 {
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);
896 }
897 return __npos;
898}
899
900
901template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
902inline _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
905{
906 if (__pos < __sz)
907 {
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);
912 }
913 return __npos;
914}
915
916
917// __str_find_last_not_of
918template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
919inline _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
922{
923 if (__pos < __sz)
924 ++__pos;
925 else
926 __pos = __sz;
927 for (const _CharT* __ps = __p + __pos; __ps != __p;)
928 if (_Traits::find(__s, __n, *--__ps) == 0)
929 return static_cast<_SizeT>(__ps - __p);
930 return __npos;
931}
932
933
934template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
935inline _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
938{
939 if (__pos < __sz)
940 ++__pos;
941 else
942 __pos = __sz;
943 for (const _CharT* __ps = __p + __pos; __ps != __p;)
944 if (!_Traits::eq(*--__ps, __c))
945 return static_cast<_SizeT>(__ps - __p);
946 return __npos;
947}
948
949template<class _Ptr>
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000950inline _LIBCPP_INLINE_VISIBILITY
951size_t __do_string_hash(_Ptr __p, _Ptr __e)
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000952{
953 typedef typename iterator_traits<_Ptr>::value_type value_type;
954 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
955}
956
957template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
958struct __quoted_output_proxy
959{
960 _Iter __first;
961 _Iter __last;
962 _CharT __delim;
963 _CharT __escape;
964
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
968};
969
970_LIBCPP_END_NAMESPACE_STD
971
Eric Fiselierf4433a32017-05-31 22:07:49 +0000972_LIBCPP_POP_MACROS
973
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000974#endif // _LIBCPP___STRING