1// -*- C++ -*-
2//===-------------------------- __string ----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STRING
11#define _LIBCPP___STRING
12
13/*
14    string synopsis
15
16namespace std
17{
18
19template <class charT>
20struct char_traits
21{
22    typedef charT     char_type;
23    typedef ...       int_type;
24    typedef streamoff off_type;
25    typedef streampos pos_type;
26    typedef mbstate_t state_type;
27
28    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
29    static constexpr bool eq(char_type c1, char_type c2) noexcept;
30    static constexpr bool lt(char_type c1, char_type c2) noexcept;
31
32    static constexpr int    compare(const char_type* s1, const char_type* s2, size_t n);
33    static constexpr size_t length(const char_type* s);
34    static constexpr const char_type*
35                            find(const char_type* s, size_t n, const char_type& a);
36
37    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
38    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
39    static constexpr char_type* assign(char_type* s, size_t n, char_type a);        // constexpr in C++20
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>;
50template <> struct char_traits<char8_t>;  // c++20
51
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
61#include <__debug>
62
63#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64#pragma GCC system_header
65#endif
66
67_LIBCPP_PUSH_MACROS
68#include <__undef_macros>
69
70
71_LIBCPP_BEGIN_NAMESPACE_STD
72
73// The the extern template ABI lists are kept outside of <string> to improve the
74// readability of that header.
75
76// The extern template ABI lists are kept outside of <string> to improve the
77// readability of that header. We maintain 2 ABI lists:
78// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
79// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
80// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
81//
82// For unstable, we may explicitly remove function that are external in V1,
83// and add (new) external functions to better control inlining and compiler
84// optimization opportunities.
85//
86// For stable, the ABI list should rarely change, except for adding new
87// functions supporting new c++ version / API changes. Typically entries
88// must never be removed from the stable list.
89#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
90  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
91  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
92  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
93  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
94  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
95  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
96  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
97  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
98  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
99  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
100  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
101  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
102  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
103  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
104  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
105  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
106  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
107  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
108  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
109  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
110  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
111  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
112  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
113  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
114  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
115  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
116  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
117  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
118  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
119  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
120  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
121  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
122  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
123  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
124  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
125  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
126  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
127  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
128  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
129  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
130  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
131  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
132  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
133  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
134  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
135  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
136  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
137  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
138
139#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
140  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
141  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
142  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
143  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
144  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
145  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
146  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
147  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
148  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
149  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
150  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
151  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
152  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
153  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
154  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
155  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
156  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
157  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
158  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
159  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
160  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
161  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
162  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
163  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
164  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
165  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
166  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
167  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
168  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
169  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
170  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
171  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
172  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
173  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
174  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
175  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
176  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
177  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
178  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
179  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
180  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
181  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
182  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
183  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
184  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
185  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
186  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
187  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
188
189
190// char_traits
191
192template <class _CharT>
193struct _LIBCPP_TEMPLATE_VIS char_traits
194{
195    typedef _CharT    char_type;
196    typedef int       int_type;
197    typedef streamoff off_type;
198    typedef streampos pos_type;
199    typedef mbstate_t state_type;
200
201    static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
202        assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
203    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
204        {return __c1 == __c2;}
205    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
206        {return __c1 < __c2;}
207
208    static _LIBCPP_CONSTEXPR_AFTER_CXX14
209    int compare(const char_type* __s1, const char_type* __s2, size_t __n);
210    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
211    size_t length(const char_type* __s);
212    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
213    const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
214    static _LIBCPP_CONSTEXPR_AFTER_CXX17
215    char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
216    _LIBCPP_INLINE_VISIBILITY
217    static _LIBCPP_CONSTEXPR_AFTER_CXX17
218    char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
219    _LIBCPP_INLINE_VISIBILITY
220    static _LIBCPP_CONSTEXPR_AFTER_CXX17
221    char_type*       assign(char_type* __s, size_t __n, char_type __a);
222
223    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
224        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
225    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
226        {return char_type(__c);}
227    static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
228        {return int_type(__c);}
229    static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
230        {return __c1 == __c2;}
231    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
232        {return int_type(EOF);}
233};
234
235template <class _CharT>
236_LIBCPP_CONSTEXPR_AFTER_CXX14 int
237char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
238{
239    for (; __n; --__n, ++__s1, ++__s2)
240    {
241        if (lt(*__s1, *__s2))
242            return -1;
243        if (lt(*__s2, *__s1))
244            return 1;
245    }
246    return 0;
247}
248
249template <class _CharT>
250inline
251_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
252char_traits<_CharT>::length(const char_type* __s)
253{
254    size_t __len = 0;
255    for (; !eq(*__s, char_type(0)); ++__s)
256        ++__len;
257    return __len;
258}
259
260template <class _CharT>
261inline
262_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
263char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
264{
265    for (; __n; --__n)
266    {
267        if (eq(*__s, __a))
268            return __s;
269        ++__s;
270    }
271    return nullptr;
272}
273
274template <class _CharT>
275_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT*
276char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
277{
278    if (__n == 0) return __s1;
279    char_type* __r = __s1;
280    if (__s1 < __s2)
281    {
282        for (; __n; --__n, ++__s1, ++__s2)
283            assign(*__s1, *__s2);
284    }
285    else if (__s2 < __s1)
286    {
287        __s1 += __n;
288        __s2 += __n;
289        for (; __n; --__n)
290            assign(*--__s1, *--__s2);
291    }
292    return __r;
293}
294
295template <class _CharT>
296inline _LIBCPP_CONSTEXPR_AFTER_CXX17
297_CharT*
298char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
299{
300    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
301    char_type* __r = __s1;
302    for (; __n; --__n, ++__s1, ++__s2)
303        assign(*__s1, *__s2);
304    return __r;
305}
306
307template <class _CharT>
308inline _LIBCPP_CONSTEXPR_AFTER_CXX17
309_CharT*
310char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
311{
312    char_type* __r = __s;
313    for (; __n; --__n, ++__s)
314        assign(*__s, __a);
315    return __r;
316}
317
318// constexpr versions of move/copy/assign.
319
320template <class _CharT>
321static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
322_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
323{
324    if (__n == 0) return __s1;
325    if (__s1 < __s2) {
326      _VSTD::copy(__s2, __s2 + __n, __s1);
327    } else if (__s2 < __s1) {
328      _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
329    }
330    return __s1;
331}
332
333template <class _CharT>
334static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
335_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
336{
337    _VSTD::copy_n(__s2, __n, __s1);
338    return __s1;
339}
340
341template <class _CharT>
342static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
343_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
344{
345     _VSTD::fill_n(__s, __n, __a);
346     return __s;
347}
348
349// char_traits<char>
350
351template <>
352struct _LIBCPP_TEMPLATE_VIS char_traits<char>
353{
354    typedef char      char_type;
355    typedef int       int_type;
356    typedef streamoff off_type;
357    typedef streampos pos_type;
358    typedef mbstate_t state_type;
359
360    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
361    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
362    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
363            {return __c1 == __c2;}
364    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
365        {return (unsigned char)__c1 < (unsigned char)__c2;}
366
367    static _LIBCPP_CONSTEXPR_AFTER_CXX14
368    int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
369    static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
370    length(const char_type* __s)  _NOEXCEPT {return __builtin_strlen(__s);}
371    static _LIBCPP_CONSTEXPR_AFTER_CXX14
372    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
373    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
374    char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
375        {
376            return __libcpp_is_constant_evaluated()
377                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
378                       : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
379        }
380    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
381    char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
382        {
383            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
384            return __libcpp_is_constant_evaluated()
385                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
386                       : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
387        }
388    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
389    char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
390        {
391            return __libcpp_is_constant_evaluated()
392                       ? _VSTD::__assign_constexpr(__s, __n, __a)
393                       : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
394        }
395
396    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
397        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
398    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
399        {return char_type(__c);}
400    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
401        {return int_type((unsigned char)__c);}
402    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
403        {return __c1 == __c2;}
404    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
405        {return int_type(EOF);}
406};
407
408inline _LIBCPP_CONSTEXPR_AFTER_CXX14
409int
410char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
411{
412    if (__n == 0)
413        return 0;
414#if __has_feature(cxx_constexpr_string_builtins)
415    return __builtin_memcmp(__s1, __s2, __n);
416#elif _LIBCPP_STD_VER <= 14
417    return memcmp(__s1, __s2, __n);
418#else
419    for (; __n; --__n, ++__s1, ++__s2)
420    {
421        if (lt(*__s1, *__s2))
422            return -1;
423        if (lt(*__s2, *__s1))
424            return 1;
425    }
426    return 0;
427#endif
428}
429
430inline _LIBCPP_CONSTEXPR_AFTER_CXX14
431const char*
432char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
433{
434    if (__n == 0)
435        return nullptr;
436#if __has_feature(cxx_constexpr_string_builtins)
437    return __builtin_char_memchr(__s, to_int_type(__a), __n);
438#elif _LIBCPP_STD_VER <= 14
439    return (const char_type*) memchr(__s, to_int_type(__a), __n);
440#else
441    for (; __n; --__n)
442    {
443        if (eq(*__s, __a))
444            return __s;
445        ++__s;
446    }
447    return nullptr;
448#endif
449}
450
451
452// char_traits<wchar_t>
453
454template <>
455struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
456{
457    typedef wchar_t   char_type;
458    typedef wint_t    int_type;
459    typedef streamoff off_type;
460    typedef streampos pos_type;
461    typedef mbstate_t state_type;
462
463    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
464    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
465    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
466        {return __c1 == __c2;}
467    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
468        {return __c1 < __c2;}
469
470    static _LIBCPP_CONSTEXPR_AFTER_CXX14
471    int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
472    static _LIBCPP_CONSTEXPR_AFTER_CXX14
473    size_t length(const char_type* __s) _NOEXCEPT;
474    static _LIBCPP_CONSTEXPR_AFTER_CXX14
475    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
476    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
477    char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
478        {
479            return __libcpp_is_constant_evaluated()
480                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
481                       : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n);
482        }
483    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
484    char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
485        {
486            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
487            return __libcpp_is_constant_evaluated()
488                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
489                       : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n);
490        }
491    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
492    char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
493        {
494            return __libcpp_is_constant_evaluated()
495                       ? _VSTD::__assign_constexpr(__s, __n, __a)
496                       : __n == 0 ? __s : wmemset(__s, __a, __n);
497        }
498    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
499        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
500    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
501        {return char_type(__c);}
502    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
503        {return int_type(__c);}
504    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
505        {return __c1 == __c2;}
506    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
507        {return int_type(WEOF);}
508};
509
510inline _LIBCPP_CONSTEXPR_AFTER_CXX14
511int
512char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
513{
514    if (__n == 0)
515        return 0;
516#if __has_feature(cxx_constexpr_string_builtins)
517    return __builtin_wmemcmp(__s1, __s2, __n);
518#elif _LIBCPP_STD_VER <= 14
519    return wmemcmp(__s1, __s2, __n);
520#else
521    for (; __n; --__n, ++__s1, ++__s2)
522    {
523        if (lt(*__s1, *__s2))
524            return -1;
525        if (lt(*__s2, *__s1))
526            return 1;
527    }
528    return 0;
529#endif
530}
531
532
533template <class _Traits>
534_LIBCPP_INLINE_VISIBILITY
535_LIBCPP_CONSTEXPR
536inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
537#if _LIBCPP_DEBUG_LEVEL >= 1
538  return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0);
539#else
540  return _Traits::length(__s);
541#endif
542}
543
544inline _LIBCPP_CONSTEXPR_AFTER_CXX14
545size_t
546char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
547{
548#if __has_feature(cxx_constexpr_string_builtins)
549    return __builtin_wcslen(__s);
550#elif _LIBCPP_STD_VER <= 14
551    return wcslen(__s);
552#else
553    size_t __len = 0;
554    for (; !eq(*__s, char_type(0)); ++__s)
555        ++__len;
556    return __len;
557#endif
558}
559
560inline _LIBCPP_CONSTEXPR_AFTER_CXX14
561const wchar_t*
562char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
563{
564    if (__n == 0)
565        return nullptr;
566#if __has_feature(cxx_constexpr_string_builtins)
567    return __builtin_wmemchr(__s, __a, __n);
568#elif _LIBCPP_STD_VER <= 14
569    return wmemchr(__s, __a, __n);
570#else
571    for (; __n; --__n)
572    {
573        if (eq(*__s, __a))
574            return __s;
575        ++__s;
576    }
577    return nullptr;
578#endif
579}
580
581
582#ifndef _LIBCPP_NO_HAS_CHAR8_T
583
584template <>
585struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
586{
587    typedef char8_t        char_type;
588    typedef unsigned int   int_type;
589    typedef streamoff      off_type;
590    typedef u8streampos    pos_type;
591    typedef mbstate_t      state_type;
592
593    static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
594        {__c1 = __c2;}
595    static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
596        {return __c1 == __c2;}
597    static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
598        {return __c1 < __c2;}
599
600    static constexpr
601    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
602
603    static constexpr
604    size_t           length(const char_type* __s) _NOEXCEPT;
605
606    _LIBCPP_INLINE_VISIBILITY static constexpr
607    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
608
609    static _LIBCPP_CONSTEXPR_AFTER_CXX17
610    char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
611        {
612            return __libcpp_is_constant_evaluated()
613                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
614                       : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
615        }
616
617    static _LIBCPP_CONSTEXPR_AFTER_CXX17
618    char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
619       {
620            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
621            return __libcpp_is_constant_evaluated()
622                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
623                       : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
624        }
625
626    static _LIBCPP_CONSTEXPR_AFTER_CXX17
627    char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
628        {
629            return __libcpp_is_constant_evaluated()
630                       ? _VSTD::__assign_constexpr(__s, __n, __a)
631                       : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
632        }
633
634    static inline constexpr int_type  not_eof(int_type __c) noexcept
635        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
636    static inline constexpr char_type to_char_type(int_type __c) noexcept
637        {return char_type(__c);}
638    static inline constexpr int_type to_int_type(char_type __c) noexcept
639        {return int_type(__c);}
640    static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
641        {return __c1 == __c2;}
642    static inline constexpr int_type eof() noexcept
643        {return int_type(EOF);}
644};
645
646// TODO use '__builtin_strlen' if it ever supports char8_t ??
647inline constexpr
648size_t
649char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
650{
651    size_t __len = 0;
652    for (; !eq(*__s, char_type(0)); ++__s)
653        ++__len;
654    return __len;
655}
656
657inline constexpr
658int
659char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
660{
661#if __has_feature(cxx_constexpr_string_builtins)
662    return __builtin_memcmp(__s1, __s2, __n);
663#else
664    for (; __n; --__n, ++__s1, ++__s2)
665    {
666        if (lt(*__s1, *__s2))
667            return -1;
668        if (lt(*__s2, *__s1))
669            return 1;
670    }
671    return 0;
672#endif
673}
674
675// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
676inline constexpr
677const char8_t*
678char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
679{
680    for (; __n; --__n)
681    {
682        if (eq(*__s, __a))
683            return __s;
684        ++__s;
685    }
686    return nullptr;
687}
688
689#endif // #_LIBCPP_NO_HAS_CHAR8_T
690
691#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
692
693template <>
694struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
695{
696    typedef char16_t       char_type;
697    typedef uint_least16_t int_type;
698    typedef streamoff      off_type;
699    typedef u16streampos   pos_type;
700    typedef mbstate_t      state_type;
701
702    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
703    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
704    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
705        {return __c1 == __c2;}
706    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
707        {return __c1 < __c2;}
708
709    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
710    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
711    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
712    size_t           length(const char_type* __s) _NOEXCEPT;
713    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
714    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
715    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
716    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
717    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
718    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
719    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
720    static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
721
722    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
723        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
724    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
725        {return char_type(__c);}
726    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
727        {return int_type(__c);}
728    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
729        {return __c1 == __c2;}
730    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
731        {return int_type(0xFFFF);}
732};
733
734inline _LIBCPP_CONSTEXPR_AFTER_CXX14
735int
736char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
737{
738    for (; __n; --__n, ++__s1, ++__s2)
739    {
740        if (lt(*__s1, *__s2))
741            return -1;
742        if (lt(*__s2, *__s1))
743            return 1;
744    }
745    return 0;
746}
747
748inline _LIBCPP_CONSTEXPR_AFTER_CXX14
749size_t
750char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
751{
752    size_t __len = 0;
753    for (; !eq(*__s, char_type(0)); ++__s)
754        ++__len;
755    return __len;
756}
757
758inline _LIBCPP_CONSTEXPR_AFTER_CXX14
759const char16_t*
760char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
761{
762    for (; __n; --__n)
763    {
764        if (eq(*__s, __a))
765            return __s;
766        ++__s;
767    }
768    return nullptr;
769}
770
771inline _LIBCPP_CONSTEXPR_AFTER_CXX17
772char16_t*
773char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
774{
775    if (__n == 0) return __s1;
776    char_type* __r = __s1;
777    if (__s1 < __s2)
778    {
779        for (; __n; --__n, ++__s1, ++__s2)
780            assign(*__s1, *__s2);
781    }
782    else if (__s2 < __s1)
783    {
784        __s1 += __n;
785        __s2 += __n;
786        for (; __n; --__n)
787            assign(*--__s1, *--__s2);
788    }
789    return __r;
790}
791
792inline _LIBCPP_CONSTEXPR_AFTER_CXX17
793char16_t*
794char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
795{
796    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
797    char_type* __r = __s1;
798    for (; __n; --__n, ++__s1, ++__s2)
799        assign(*__s1, *__s2);
800    return __r;
801}
802
803inline _LIBCPP_CONSTEXPR_AFTER_CXX17
804char16_t*
805char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
806{
807    char_type* __r = __s;
808    for (; __n; --__n, ++__s)
809        assign(*__s, __a);
810    return __r;
811}
812
813template <>
814struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
815{
816    typedef char32_t       char_type;
817    typedef uint_least32_t int_type;
818    typedef streamoff      off_type;
819    typedef u32streampos   pos_type;
820    typedef mbstate_t      state_type;
821
822    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
823    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
824    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
825        {return __c1 == __c2;}
826    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
827        {return __c1 < __c2;}
828
829    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
830    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
831    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
832    size_t           length(const char_type* __s) _NOEXCEPT;
833    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
834    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
835    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
836    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
837    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
838    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
839    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
840    static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
841
842    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
843        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
844    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
845        {return char_type(__c);}
846    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
847        {return int_type(__c);}
848    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
849        {return __c1 == __c2;}
850    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
851        {return int_type(0xFFFFFFFF);}
852};
853
854inline _LIBCPP_CONSTEXPR_AFTER_CXX14
855int
856char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
857{
858    for (; __n; --__n, ++__s1, ++__s2)
859    {
860        if (lt(*__s1, *__s2))
861            return -1;
862        if (lt(*__s2, *__s1))
863            return 1;
864    }
865    return 0;
866}
867
868inline _LIBCPP_CONSTEXPR_AFTER_CXX14
869size_t
870char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
871{
872    size_t __len = 0;
873    for (; !eq(*__s, char_type(0)); ++__s)
874        ++__len;
875    return __len;
876}
877
878inline _LIBCPP_CONSTEXPR_AFTER_CXX14
879const char32_t*
880char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
881{
882    for (; __n; --__n)
883    {
884        if (eq(*__s, __a))
885            return __s;
886        ++__s;
887    }
888    return nullptr;
889}
890
891inline _LIBCPP_CONSTEXPR_AFTER_CXX17
892char32_t*
893char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
894{
895    if (__n == 0) return __s1;
896    char_type* __r = __s1;
897    if (__s1 < __s2)
898    {
899        for (; __n; --__n, ++__s1, ++__s2)
900            assign(*__s1, *__s2);
901    }
902    else if (__s2 < __s1)
903    {
904        __s1 += __n;
905        __s2 += __n;
906        for (; __n; --__n)
907            assign(*--__s1, *--__s2);
908    }
909    return __r;
910}
911
912inline _LIBCPP_CONSTEXPR_AFTER_CXX17
913char32_t*
914char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
915{
916    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
917    char_type* __r = __s1;
918    for (; __n; --__n, ++__s1, ++__s2)
919        assign(*__s1, *__s2);
920    return __r;
921}
922
923inline _LIBCPP_CONSTEXPR_AFTER_CXX17
924char32_t*
925char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
926{
927    char_type* __r = __s;
928    for (; __n; --__n, ++__s)
929        assign(*__s, __a);
930    return __r;
931}
932
933#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
934
935// helper fns for basic_string and string_view
936
937// __str_find
938template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
939inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
940__str_find(const _CharT *__p, _SizeT __sz,
941             _CharT __c, _SizeT __pos) _NOEXCEPT
942{
943    if (__pos >= __sz)
944        return __npos;
945    const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
946    if (__r == nullptr)
947        return __npos;
948    return static_cast<_SizeT>(__r - __p);
949}
950
951template <class _CharT, class _Traits>
952inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
953__search_substring(const _CharT *__first1, const _CharT *__last1,
954                   const _CharT *__first2, const _CharT *__last2) {
955  // Take advantage of knowing source and pattern lengths.
956  // Stop short when source is smaller than pattern.
957  const ptrdiff_t __len2 = __last2 - __first2;
958  if (__len2 == 0)
959    return __first1;
960
961  ptrdiff_t __len1 = __last1 - __first1;
962  if (__len1 < __len2)
963    return __last1;
964
965  // First element of __first2 is loop invariant.
966  _CharT __f2 = *__first2;
967  while (true) {
968    __len1 = __last1 - __first1;
969    // Check whether __first1 still has at least __len2 bytes.
970    if (__len1 < __len2)
971      return __last1;
972
973    // Find __f2 the first byte matching in __first1.
974    __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
975    if (__first1 == nullptr)
976      return __last1;
977
978    // It is faster to compare from the first byte of __first1 even if we
979    // already know that it matches the first byte of __first2: this is because
980    // __first2 is most likely aligned, as it is user's "pattern" string, and
981    // __first1 + 1 is most likely not aligned, as the match is in the middle of
982    // the string.
983    if (_Traits::compare(__first1, __first2, __len2) == 0)
984      return __first1;
985
986    ++__first1;
987  }
988}
989
990template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
991inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
992__str_find(const _CharT *__p, _SizeT __sz,
993       const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
994{
995    if (__pos > __sz)
996        return __npos;
997
998    if (__n == 0) // There is nothing to search, just return __pos.
999        return __pos;
1000
1001    const _CharT *__r = __search_substring<_CharT, _Traits>(
1002        __p + __pos, __p + __sz, __s, __s + __n);
1003
1004    if (__r == __p + __sz)
1005        return __npos;
1006    return static_cast<_SizeT>(__r - __p);
1007}
1008
1009
1010// __str_rfind
1011
1012template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1013inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1014__str_rfind(const _CharT *__p, _SizeT __sz,
1015              _CharT __c, _SizeT __pos) _NOEXCEPT
1016{
1017    if (__sz < 1)
1018        return __npos;
1019    if (__pos < __sz)
1020        ++__pos;
1021    else
1022        __pos = __sz;
1023    for (const _CharT* __ps = __p + __pos; __ps != __p;)
1024    {
1025        if (_Traits::eq(*--__ps, __c))
1026            return static_cast<_SizeT>(__ps - __p);
1027    }
1028    return __npos;
1029}
1030
1031template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1032inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1033__str_rfind(const _CharT *__p, _SizeT __sz,
1034        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1035{
1036    __pos = _VSTD::min(__pos, __sz);
1037    if (__n < __sz - __pos)
1038        __pos += __n;
1039    else
1040        __pos = __sz;
1041    const _CharT* __r = _VSTD::__find_end(
1042                  __p, __p + __pos, __s, __s + __n, _Traits::eq,
1043                        random_access_iterator_tag(), random_access_iterator_tag());
1044    if (__n > 0 && __r == __p + __pos)
1045        return __npos;
1046    return static_cast<_SizeT>(__r - __p);
1047}
1048
1049// __str_find_first_of
1050template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1051inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1052__str_find_first_of(const _CharT *__p, _SizeT __sz,
1053                const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1054{
1055    if (__pos >= __sz || __n == 0)
1056        return __npos;
1057    const _CharT* __r = _VSTD::__find_first_of_ce
1058        (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
1059    if (__r == __p + __sz)
1060        return __npos;
1061    return static_cast<_SizeT>(__r - __p);
1062}
1063
1064
1065// __str_find_last_of
1066template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1067inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1068__str_find_last_of(const _CharT *__p, _SizeT __sz,
1069               const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1070    {
1071    if (__n != 0)
1072    {
1073        if (__pos < __sz)
1074            ++__pos;
1075        else
1076            __pos = __sz;
1077        for (const _CharT* __ps = __p + __pos; __ps != __p;)
1078        {
1079            const _CharT* __r = _Traits::find(__s, __n, *--__ps);
1080            if (__r)
1081                return static_cast<_SizeT>(__ps - __p);
1082        }
1083    }
1084    return __npos;
1085}
1086
1087
1088// __str_find_first_not_of
1089template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1090inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1091__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1092                    const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1093{
1094    if (__pos < __sz)
1095    {
1096        const _CharT* __pe = __p + __sz;
1097        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1098            if (_Traits::find(__s, __n, *__ps) == nullptr)
1099                return static_cast<_SizeT>(__ps - __p);
1100    }
1101    return __npos;
1102}
1103
1104
1105template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1106inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1107__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1108                          _CharT __c, _SizeT __pos) _NOEXCEPT
1109{
1110    if (__pos < __sz)
1111    {
1112        const _CharT* __pe = __p + __sz;
1113        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1114            if (!_Traits::eq(*__ps, __c))
1115                return static_cast<_SizeT>(__ps - __p);
1116    }
1117    return __npos;
1118}
1119
1120
1121// __str_find_last_not_of
1122template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1123inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1124__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1125                   const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1126{
1127    if (__pos < __sz)
1128        ++__pos;
1129    else
1130        __pos = __sz;
1131    for (const _CharT* __ps = __p + __pos; __ps != __p;)
1132        if (_Traits::find(__s, __n, *--__ps) == nullptr)
1133            return static_cast<_SizeT>(__ps - __p);
1134    return __npos;
1135}
1136
1137
1138template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1139inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1140__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1141                         _CharT __c, _SizeT __pos) _NOEXCEPT
1142{
1143    if (__pos < __sz)
1144        ++__pos;
1145    else
1146        __pos = __sz;
1147    for (const _CharT* __ps = __p + __pos; __ps != __p;)
1148        if (!_Traits::eq(*--__ps, __c))
1149            return static_cast<_SizeT>(__ps - __p);
1150    return __npos;
1151}
1152
1153template<class _Ptr>
1154inline _LIBCPP_INLINE_VISIBILITY
1155size_t __do_string_hash(_Ptr __p, _Ptr __e)
1156{
1157    typedef typename iterator_traits<_Ptr>::value_type value_type;
1158    return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
1159}
1160
1161template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
1162struct __quoted_output_proxy
1163{
1164    _Iter  __first;
1165    _Iter  __last;
1166    _CharT  __delim;
1167    _CharT  __escape;
1168
1169    __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
1170    : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
1171    //  This would be a nice place for a string_ref
1172};
1173
1174_LIBCPP_END_NAMESPACE_STD
1175
1176_LIBCPP_POP_MACROS
1177
1178#endif  // _LIBCPP___STRING
1179