blob: 0b851b9f9e2be6779d07467c4ec38a3e1e2ad49e [file] [log] [blame]
Marshall Clow1e00d6d2016-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
29 static 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;
32
33 static int compare(const char_type* s1, const char_type* s2, size_t n);
34 static size_t length(const char_type* s);
35 static const char_type* find(const char_type* s, size_t n, const char_type& a);
36 static char_type* move(char_type* s1, const char_type* s2, size_t n);
37 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
38 static char_type* assign(char_type* s, size_t n, char_type a);
39
40 static constexpr int_type not_eof(int_type c) noexcept;
41 static constexpr char_type to_char_type(int_type c) noexcept;
42 static constexpr int_type to_int_type(char_type c) noexcept;
43 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
44 static constexpr int_type eof() noexcept;
45};
46
47template <> struct char_traits<char>;
48template <> struct char_traits<wchar_t>;
49
50} // std
51
52*/
53
54#include <__config>
55#include <algorithm> // for search and min
56#include <cstdio> // For EOF.
57#include <memory> // for __murmur2_or_cityhash
58
59#include <__undef_min_max>
60
61#include <__debug>
62
63#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64#pragma GCC system_header
65#endif
66
67_LIBCPP_BEGIN_NAMESPACE_STD
68
69// char_traits
70
71template <class _CharT>
Eric Fiselierc3589a82017-01-04 23:56:00 +000072struct _LIBCPP_TEMPLATE_VIS char_traits
Marshall Clow1e00d6d2016-07-21 05:31:24 +000073{
74 typedef _CharT char_type;
75 typedef int int_type;
76 typedef streamoff off_type;
77 typedef streampos pos_type;
78 typedef mbstate_t state_type;
79
80 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
81 {__c1 = __c2;}
82 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
83 {return __c1 == __c2;}
84 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
85 {return __c1 < __c2;}
86
87 static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
88 _LIBCPP_INLINE_VISIBILITY
89 static size_t length(const char_type* __s);
90 _LIBCPP_INLINE_VISIBILITY
91 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
92 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
93 _LIBCPP_INLINE_VISIBILITY
94 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
95 _LIBCPP_INLINE_VISIBILITY
96 static char_type* assign(char_type* __s, size_t __n, char_type __a);
97
98 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
99 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
100 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
101 {return char_type(__c);}
102 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
103 {return int_type(__c);}
104 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
105 {return __c1 == __c2;}
106 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
107 {return int_type(EOF);}
108};
109
110template <class _CharT>
111int
112char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
113{
114 for (; __n; --__n, ++__s1, ++__s2)
115 {
116 if (lt(*__s1, *__s2))
117 return -1;
118 if (lt(*__s2, *__s1))
119 return 1;
120 }
121 return 0;
122}
123
124template <class _CharT>
125inline
126size_t
127char_traits<_CharT>::length(const char_type* __s)
128{
129 size_t __len = 0;
130 for (; !eq(*__s, char_type(0)); ++__s)
131 ++__len;
132 return __len;
133}
134
135template <class _CharT>
136inline
137const _CharT*
138char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
139{
140 for (; __n; --__n)
141 {
142 if (eq(*__s, __a))
143 return __s;
144 ++__s;
145 }
146 return 0;
147}
148
149template <class _CharT>
150_CharT*
151char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
152{
153 char_type* __r = __s1;
154 if (__s1 < __s2)
155 {
156 for (; __n; --__n, ++__s1, ++__s2)
157 assign(*__s1, *__s2);
158 }
159 else if (__s2 < __s1)
160 {
161 __s1 += __n;
162 __s2 += __n;
163 for (; __n; --__n)
164 assign(*--__s1, *--__s2);
165 }
166 return __r;
167}
168
169template <class _CharT>
170inline
171_CharT*
172char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
173{
174 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
175 char_type* __r = __s1;
176 for (; __n; --__n, ++__s1, ++__s2)
177 assign(*__s1, *__s2);
178 return __r;
179}
180
181template <class _CharT>
182inline
183_CharT*
184char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
185{
186 char_type* __r = __s;
187 for (; __n; --__n, ++__s)
188 assign(*__s, __a);
189 return __r;
190}
191
192// char_traits<char>
193
194template <>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000195struct _LIBCPP_TEMPLATE_VIS char_traits<char>
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000196{
197 typedef char char_type;
198 typedef int int_type;
199 typedef streamoff off_type;
200 typedef streampos pos_type;
201 typedef mbstate_t state_type;
202
203 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
204 {__c1 = __c2;}
205 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
206 {return __c1 == __c2;}
207 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
208 {return (unsigned char)__c1 < (unsigned char)__c2;}
209
Marshall Clowe6521d62016-07-28 04:52:02 +0000210 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000211 {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000212 static inline size_t length(const char_type* __s) _NOEXCEPT {return strlen(__s);}
213 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000214 {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000215 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000216 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000217 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000218 {
219 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
220 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
221 }
Marshall Clowe6521d62016-07-28 04:52:02 +0000222 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000223 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
224
225 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
226 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
227 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
228 {return char_type(__c);}
229 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
230 {return int_type((unsigned char)__c);}
231 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
232 {return __c1 == __c2;}
233 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
234 {return int_type(EOF);}
235};
236
237// char_traits<wchar_t>
238
239template <>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000240struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000241{
242 typedef wchar_t char_type;
243 typedef wint_t int_type;
244 typedef streamoff off_type;
245 typedef streampos pos_type;
246 typedef mbstate_t state_type;
247
248 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
249 {__c1 = __c2;}
250 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
251 {return __c1 == __c2;}
252 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
253 {return __c1 < __c2;}
254
Marshall Clowe6521d62016-07-28 04:52:02 +0000255 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000256 {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000257 static inline size_t length(const char_type* __s) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000258 {return wcslen(__s);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000259 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000260 {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000261 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000262 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
Marshall Clowe6521d62016-07-28 04:52:02 +0000263 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000264 {
265 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
266 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
267 }
Marshall Clowe6521d62016-07-28 04:52:02 +0000268 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000269 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
270
271 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
272 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
273 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
274 {return char_type(__c);}
275 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
276 {return int_type(__c);}
277 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
278 {return __c1 == __c2;}
279 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
280 {return int_type(WEOF);}
281};
282
283#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
284
285template <>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000286struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000287{
288 typedef char16_t char_type;
289 typedef uint_least16_t int_type;
290 typedef streamoff off_type;
291 typedef u16streampos pos_type;
292 typedef mbstate_t state_type;
293
294 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
295 {__c1 = __c2;}
296 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
297 {return __c1 == __c2;}
298 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
299 {return __c1 < __c2;}
300
301 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000302 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000303 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000304 static size_t length(const char_type* __s) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000305 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000306 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000307 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000308 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000309 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000310 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000311 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000312 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000313
314 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
315 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
316 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
317 {return char_type(__c);}
318 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
319 {return int_type(__c);}
320 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
321 {return __c1 == __c2;}
322 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
323 {return int_type(0xFFFF);}
324};
325
326inline
327int
Marshall Clowe6521d62016-07-28 04:52:02 +0000328char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000329{
330 for (; __n; --__n, ++__s1, ++__s2)
331 {
332 if (lt(*__s1, *__s2))
333 return -1;
334 if (lt(*__s2, *__s1))
335 return 1;
336 }
337 return 0;
338}
339
340inline
341size_t
Marshall Clowe6521d62016-07-28 04:52:02 +0000342char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000343{
344 size_t __len = 0;
345 for (; !eq(*__s, char_type(0)); ++__s)
346 ++__len;
347 return __len;
348}
349
350inline
351const char16_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000352char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000353{
354 for (; __n; --__n)
355 {
356 if (eq(*__s, __a))
357 return __s;
358 ++__s;
359 }
360 return 0;
361}
362
363inline
364char16_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000365char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000366{
367 char_type* __r = __s1;
368 if (__s1 < __s2)
369 {
370 for (; __n; --__n, ++__s1, ++__s2)
371 assign(*__s1, *__s2);
372 }
373 else if (__s2 < __s1)
374 {
375 __s1 += __n;
376 __s2 += __n;
377 for (; __n; --__n)
378 assign(*--__s1, *--__s2);
379 }
380 return __r;
381}
382
383inline
384char16_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000385char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000386{
387 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
388 char_type* __r = __s1;
389 for (; __n; --__n, ++__s1, ++__s2)
390 assign(*__s1, *__s2);
391 return __r;
392}
393
394inline
395char16_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000396char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000397{
398 char_type* __r = __s;
399 for (; __n; --__n, ++__s)
400 assign(*__s, __a);
401 return __r;
402}
403
404template <>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000405struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000406{
407 typedef char32_t char_type;
408 typedef uint_least32_t int_type;
409 typedef streamoff off_type;
410 typedef u32streampos pos_type;
411 typedef mbstate_t state_type;
412
413 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
414 {__c1 = __c2;}
415 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
416 {return __c1 == __c2;}
417 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
418 {return __c1 < __c2;}
419
420 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000421 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000422 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000423 static size_t length(const char_type* __s) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000424 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000425 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000426 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000427 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000428 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000429 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000430 _LIBCPP_INLINE_VISIBILITY
Marshall Clowe6521d62016-07-28 04:52:02 +0000431 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000432
433 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
434 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
435 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
436 {return char_type(__c);}
437 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
438 {return int_type(__c);}
439 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
440 {return __c1 == __c2;}
441 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
442 {return int_type(0xFFFFFFFF);}
443};
444
445inline
446int
Marshall Clowe6521d62016-07-28 04:52:02 +0000447char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000448{
449 for (; __n; --__n, ++__s1, ++__s2)
450 {
451 if (lt(*__s1, *__s2))
452 return -1;
453 if (lt(*__s2, *__s1))
454 return 1;
455 }
456 return 0;
457}
458
459inline
460size_t
Marshall Clowe6521d62016-07-28 04:52:02 +0000461char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000462{
463 size_t __len = 0;
464 for (; !eq(*__s, char_type(0)); ++__s)
465 ++__len;
466 return __len;
467}
468
469inline
470const char32_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000471char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000472{
473 for (; __n; --__n)
474 {
475 if (eq(*__s, __a))
476 return __s;
477 ++__s;
478 }
479 return 0;
480}
481
482inline
483char32_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000484char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000485{
486 char_type* __r = __s1;
487 if (__s1 < __s2)
488 {
489 for (; __n; --__n, ++__s1, ++__s2)
490 assign(*__s1, *__s2);
491 }
492 else if (__s2 < __s1)
493 {
494 __s1 += __n;
495 __s2 += __n;
496 for (; __n; --__n)
497 assign(*--__s1, *--__s2);
498 }
499 return __r;
500}
501
502inline
503char32_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000504char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000505{
506 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
507 char_type* __r = __s1;
508 for (; __n; --__n, ++__s1, ++__s2)
509 assign(*__s1, *__s2);
510 return __r;
511}
512
513inline
514char32_t*
Marshall Clowe6521d62016-07-28 04:52:02 +0000515char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000516{
517 char_type* __r = __s;
518 for (; __n; --__n, ++__s)
519 assign(*__s, __a);
520 return __r;
521}
522
523#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
524
525// helper fns for basic_string and string_view
526
527// __str_find
528template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
529inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
530__str_find(const _CharT *__p, _SizeT __sz,
531 _CharT __c, _SizeT __pos) _NOEXCEPT
532{
533 if (__pos >= __sz)
534 return __npos;
535 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
536 if (__r == 0)
537 return __npos;
538 return static_cast<_SizeT>(__r - __p);
539}
540
Sebastian Pop51dfbbc2016-12-30 18:01:36 +0000541template <class _CharT, class _Traits>
542inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
543__search_substring(const _CharT *__first1, const _CharT *__last1,
544 const _CharT *__first2, const _CharT *__last2) {
545 // Take advantage of knowing source and pattern lengths.
546 // Stop short when source is smaller than pattern.
547 const ptrdiff_t __len2 = __last2 - __first2;
548 if (__len2 == 0)
549 return __first1;
550
551 ptrdiff_t __len1 = __last1 - __first1;
552 if (__len1 < __len2)
553 return __last1;
554
555 // First element of __first2 is loop invariant.
556 _CharT __f2 = *__first2;
557 while (true) {
558 __len1 = __last1 - __first1;
559 // Check whether __first1 still has at least __len2 bytes.
560 if (__len1 < __len2)
561 return __last1;
562
563 // Find __f2 the first byte matching in __first1.
564 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
565 if (__first1 == 0)
566 return __last1;
567
568 // It is faster to compare from the first byte of __first1 even if we
569 // already know that it matches the first byte of __first2: this is because
570 // __first2 is most likely aligned, as it is user's "pattern" string, and
571 // __first1 + 1 is most likely not aligned, as the match is in the middle of
572 // the string.
573 if (_Traits::compare(__first1, __first2, __len2) == 0)
574 return __first1;
575
576 ++__first1;
577 }
578}
579
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000580template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
581inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
582__str_find(const _CharT *__p, _SizeT __sz,
583 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
584{
Sebastian Pop51dfbbc2016-12-30 18:01:36 +0000585 if (__pos > __sz)
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000586 return __npos;
Sebastian Pop51dfbbc2016-12-30 18:01:36 +0000587
588 if (__n == 0) // There is nothing to search, just return __pos.
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000589 return __pos;
Sebastian Pop51dfbbc2016-12-30 18:01:36 +0000590
591 const _CharT *__r = __search_substring<_CharT, _Traits>(
592 __p + __pos, __p + __sz, __s, __s + __n);
593
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000594 if (__r == __p + __sz)
595 return __npos;
596 return static_cast<_SizeT>(__r - __p);
597}
598
599
600// __str_rfind
601
602template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
603inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
604__str_rfind(const _CharT *__p, _SizeT __sz,
605 _CharT __c, _SizeT __pos) _NOEXCEPT
606{
607 if (__sz < 1)
608 return __npos;
609 if (__pos < __sz)
610 ++__pos;
611 else
612 __pos = __sz;
613 for (const _CharT* __ps = __p + __pos; __ps != __p;)
614 {
615 if (_Traits::eq(*--__ps, __c))
616 return static_cast<_SizeT>(__ps - __p);
617 }
618 return __npos;
619}
620
621template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
622inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
623__str_rfind(const _CharT *__p, _SizeT __sz,
624 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
625{
626 __pos = _VSTD::min(__pos, __sz);
627 if (__n < __sz - __pos)
628 __pos += __n;
629 else
630 __pos = __sz;
631 const _CharT* __r = _VSTD::__find_end(
632 __p, __p + __pos, __s, __s + __n, _Traits::eq,
633 random_access_iterator_tag(), random_access_iterator_tag());
634 if (__n > 0 && __r == __p + __pos)
635 return __npos;
636 return static_cast<_SizeT>(__r - __p);
637}
638
639// __str_find_first_of
640template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
641inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
642__str_find_first_of(const _CharT *__p, _SizeT __sz,
643 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
644{
645 if (__pos >= __sz || __n == 0)
646 return __npos;
647 const _CharT* __r = _VSTD::__find_first_of_ce
648 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
649 if (__r == __p + __sz)
650 return __npos;
651 return static_cast<_SizeT>(__r - __p);
652}
653
654
655// __str_find_last_of
656template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
657inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
658__str_find_last_of(const _CharT *__p, _SizeT __sz,
659 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
660 {
661 if (__n != 0)
662 {
663 if (__pos < __sz)
664 ++__pos;
665 else
666 __pos = __sz;
667 for (const _CharT* __ps = __p + __pos; __ps != __p;)
668 {
669 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
670 if (__r)
671 return static_cast<_SizeT>(__ps - __p);
672 }
673 }
674 return __npos;
675}
676
677
678// __str_find_first_not_of
679template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
680inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
681__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
682 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
683{
684 if (__pos < __sz)
685 {
686 const _CharT* __pe = __p + __sz;
687 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
688 if (_Traits::find(__s, __n, *__ps) == 0)
689 return static_cast<_SizeT>(__ps - __p);
690 }
691 return __npos;
692}
693
694
695template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
696inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
697__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
698 _CharT __c, _SizeT __pos) _NOEXCEPT
699{
700 if (__pos < __sz)
701 {
702 const _CharT* __pe = __p + __sz;
703 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
704 if (!_Traits::eq(*__ps, __c))
705 return static_cast<_SizeT>(__ps - __p);
706 }
707 return __npos;
708}
709
710
711// __str_find_last_not_of
712template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
713inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
714__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
715 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
716{
717 if (__pos < __sz)
718 ++__pos;
719 else
720 __pos = __sz;
721 for (const _CharT* __ps = __p + __pos; __ps != __p;)
722 if (_Traits::find(__s, __n, *--__ps) == 0)
723 return static_cast<_SizeT>(__ps - __p);
724 return __npos;
725}
726
727
728template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
729inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
730__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
731 _CharT __c, _SizeT __pos) _NOEXCEPT
732{
733 if (__pos < __sz)
734 ++__pos;
735 else
736 __pos = __sz;
737 for (const _CharT* __ps = __p + __pos; __ps != __p;)
738 if (!_Traits::eq(*--__ps, __c))
739 return static_cast<_SizeT>(__ps - __p);
740 return __npos;
741}
742
743template<class _Ptr>
Eric Fiselier833d6442016-09-15 22:27:07 +0000744inline _LIBCPP_INLINE_VISIBILITY
745size_t __do_string_hash(_Ptr __p, _Ptr __e)
Marshall Clow1e00d6d2016-07-21 05:31:24 +0000746{
747 typedef typename iterator_traits<_Ptr>::value_type value_type;
748 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
749}
750
751template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
752struct __quoted_output_proxy
753{
754 _Iter __first;
755 _Iter __last;
756 _CharT __delim;
757 _CharT __escape;
758
759 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
760 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
761 // This would be a nice place for a string_ref
762};
763
764_LIBCPP_END_NAMESPACE_STD
765
766#endif // _LIBCPP___STRING