blob: 45060c282d5918db586173ff48ea4d80fbfc5489 [file] [log] [blame]
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001// -*- C++ -*-
2//===-------------------------- __string ----------------------------------===//
3//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// 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
Marshall Clowdf63a6d2016-07-21 05:31:24 +00007//
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
Marshall Clow951035b2017-01-12 04:37:14 +000028 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
Marshall Clowdf63a6d2016-07-21 05:31:24 +000029 static constexpr bool eq(char_type c1, char_type c2) noexcept;
30 static constexpr bool lt(char_type c1, char_type c2) noexcept;
31
Marshall Clow951035b2017-01-12 04:37:14 +000032 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);
Louis Dionnefd77e4f2019-10-23 10:40:15 -070034 static constexpr const char_type*
Marshall Clow951035b2017-01-12 04:37:14 +000035 find(const char_type* s, size_t n, const char_type& a);
Michael Parkb5f44472019-11-08 13:42:26 +000036
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
Marshall Clowdf63a6d2016-07-21 05:31:24 +000040
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
Eric Fiselier5dcce5c2020-01-15 17:12:09 -050073// The the extern template ABI lists are kept outside of <string> to improve the
74// readability of that header.
Martijn Vels1e63ba02020-02-19 16:27:50 -050075
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&, std::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, std::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) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500140 _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)) \
Martijn Velsad633422020-03-04 14:51:21 -0500143 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500144 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
Martijn Velsad633422020-03-04 14:51:21 -0500145 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500146 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
147 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
148 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
149 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
150 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
151 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
152 _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
153 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
154 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
155 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
156 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
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, std::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*)) \
Martijn Vels596e3de2020-02-26 15:55:49 -0500168 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
169 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500170 _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)) \
Martijn Velsa81fc792020-02-26 13:25:43 -0500175 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500176 _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>& basic_string<_CharType>::assign(value_type const*)) \
181 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
182 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
183 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
Eric Fiselier5dcce5c2020-01-15 17:12:09 -0500184 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
185 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
186 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
187 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
188 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
189
190
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000191// char_traits
192
193template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000194struct _LIBCPP_TEMPLATE_VIS char_traits
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000195{
196 typedef _CharT char_type;
197 typedef int int_type;
198 typedef streamoff off_type;
199 typedef streampos pos_type;
200 typedef mbstate_t state_type;
201
Marshall Clow951035b2017-01-12 04:37:14 +0000202 static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
203 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000204 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
205 {return __c1 == __c2;}
206 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
207 {return __c1 < __c2;}
208
Marshall Clow951035b2017-01-12 04:37:14 +0000209 static _LIBCPP_CONSTEXPR_AFTER_CXX14
210 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
211 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
212 size_t length(const char_type* __s);
213 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
214 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
Michael Parkb5f44472019-11-08 13:42:26 +0000215 static _LIBCPP_CONSTEXPR_AFTER_CXX17
216 char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000217 _LIBCPP_INLINE_VISIBILITY
Michael Parkb5f44472019-11-08 13:42:26 +0000218 static _LIBCPP_CONSTEXPR_AFTER_CXX17
219 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000220 _LIBCPP_INLINE_VISIBILITY
Michael Parkb5f44472019-11-08 13:42:26 +0000221 static _LIBCPP_CONSTEXPR_AFTER_CXX17
222 char_type* assign(char_type* __s, size_t __n, char_type __a);
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000223
224 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
225 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
226 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
227 {return char_type(__c);}
228 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
229 {return int_type(__c);}
230 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
231 {return __c1 == __c2;}
232 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
233 {return int_type(EOF);}
234};
235
236template <class _CharT>
Marshall Clow951035b2017-01-12 04:37:14 +0000237_LIBCPP_CONSTEXPR_AFTER_CXX14 int
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000238char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
239{
240 for (; __n; --__n, ++__s1, ++__s2)
241 {
242 if (lt(*__s1, *__s2))
243 return -1;
244 if (lt(*__s2, *__s1))
245 return 1;
246 }
247 return 0;
248}
249
250template <class _CharT>
251inline
Marshall Clow951035b2017-01-12 04:37:14 +0000252_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000253char_traits<_CharT>::length(const char_type* __s)
254{
255 size_t __len = 0;
256 for (; !eq(*__s, char_type(0)); ++__s)
257 ++__len;
258 return __len;
259}
260
261template <class _CharT>
262inline
Marshall Clow951035b2017-01-12 04:37:14 +0000263_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000264char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
265{
266 for (; __n; --__n)
267 {
268 if (eq(*__s, __a))
269 return __s;
270 ++__s;
271 }
272 return 0;
273}
274
275template <class _CharT>
Michael Parkb5f44472019-11-08 13:42:26 +0000276_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT*
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000277char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
278{
Michael Parkb5f44472019-11-08 13:42:26 +0000279 if (__n == 0) return __s1;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000280 char_type* __r = __s1;
281 if (__s1 < __s2)
282 {
283 for (; __n; --__n, ++__s1, ++__s2)
284 assign(*__s1, *__s2);
285 }
286 else if (__s2 < __s1)
287 {
288 __s1 += __n;
289 __s2 += __n;
290 for (; __n; --__n)
291 assign(*--__s1, *--__s2);
292 }
293 return __r;
294}
295
296template <class _CharT>
Michael Parkb5f44472019-11-08 13:42:26 +0000297inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000298_CharT*
299char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
300{
301 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
302 char_type* __r = __s1;
303 for (; __n; --__n, ++__s1, ++__s2)
304 assign(*__s1, *__s2);
305 return __r;
306}
307
308template <class _CharT>
Michael Parkb5f44472019-11-08 13:42:26 +0000309inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000310_CharT*
311char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
312{
313 char_type* __r = __s;
314 for (; __n; --__n, ++__s)
315 assign(*__s, __a);
316 return __r;
317}
318
Michael Parkb5f44472019-11-08 13:42:26 +0000319// constexpr versions of move/copy/assign.
320
321template <class _CharT>
322static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
323_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
324{
325 if (__n == 0) return __s1;
326 if (__s1 < __s2) {
327 _VSTD::copy(__s2, __s2 + __n, __s1);
328 } else if (__s2 < __s1) {
329 _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
330 }
331 return __s1;
332}
333
334template <class _CharT>
335static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
336_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
337{
338 _VSTD::copy_n(__s2, __n, __s1);
339 return __s1;
340}
341
342template <class _CharT>
343static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
344_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
345{
346 _VSTD::fill_n(__s, __n, __a);
347 return __s;
348}
349
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000350// char_traits<char>
351
352template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000353struct _LIBCPP_TEMPLATE_VIS char_traits<char>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000354{
355 typedef char char_type;
356 typedef int int_type;
357 typedef streamoff off_type;
358 typedef streampos pos_type;
359 typedef mbstate_t state_type;
360
Marshall Clow951035b2017-01-12 04:37:14 +0000361 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
362 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000363 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
364 {return __c1 == __c2;}
365 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
366 {return (unsigned char)__c1 < (unsigned char)__c2;}
367
Marshall Clowaa32f162017-01-12 05:40:58 +0000368 static _LIBCPP_CONSTEXPR_AFTER_CXX14
369 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Marshall Clow951035b2017-01-12 04:37:14 +0000370 static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
371 length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
372 static _LIBCPP_CONSTEXPR_AFTER_CXX14
373 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000374 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
375 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
376 {
377 return __libcpp_is_constant_evaluated()
378 ? __move_constexpr(__s1, __s2, __n)
379 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
380 }
381 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
382 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000383 {
384 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkb5f44472019-11-08 13:42:26 +0000385 return __libcpp_is_constant_evaluated()
386 ? __copy_constexpr(__s1, __s2, __n)
387 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000388 }
Michael Parkb5f44472019-11-08 13:42:26 +0000389 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
390 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
391 {
392 return __libcpp_is_constant_evaluated()
393 ? __assign_constexpr(__s, __n, __a)
394 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
395 }
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000396
397 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
398 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
399 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
400 {return char_type(__c);}
401 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
402 {return int_type((unsigned char)__c);}
403 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
404 {return __c1 == __c2;}
405 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
406 {return int_type(EOF);}
407};
408
Marshall Clow951035b2017-01-12 04:37:14 +0000409inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowaa32f162017-01-12 05:40:58 +0000410int
411char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
412{
413 if (__n == 0)
414 return 0;
Marshall Clowb344c362017-01-26 06:58:29 +0000415#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clowaa32f162017-01-12 05:40:58 +0000416 return __builtin_memcmp(__s1, __s2, __n);
417#elif _LIBCPP_STD_VER <= 14
418 return memcmp(__s1, __s2, __n);
419#else
420 for (; __n; --__n, ++__s1, ++__s2)
421 {
422 if (lt(*__s1, *__s2))
423 return -1;
424 if (lt(*__s2, *__s1))
425 return 1;
426 }
427 return 0;
428#endif
429}
430
431inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clow951035b2017-01-12 04:37:14 +0000432const char*
433char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
434{
435 if (__n == 0)
Marshall Clow32043ac2018-02-06 18:58:05 +0000436 return nullptr;
Marshall Clowb344c362017-01-26 06:58:29 +0000437#if __has_feature(cxx_constexpr_string_builtins)
438 return __builtin_char_memchr(__s, to_int_type(__a), __n);
439#elif _LIBCPP_STD_VER <= 14
Marshall Clow951035b2017-01-12 04:37:14 +0000440 return (const char_type*) memchr(__s, to_int_type(__a), __n);
441#else
442 for (; __n; --__n)
443 {
444 if (eq(*__s, __a))
445 return __s;
446 ++__s;
447 }
Marshall Clow32043ac2018-02-06 18:58:05 +0000448 return nullptr;
Marshall Clow951035b2017-01-12 04:37:14 +0000449#endif
450}
451
452
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000453// char_traits<wchar_t>
454
455template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000456struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000457{
458 typedef wchar_t char_type;
459 typedef wint_t int_type;
460 typedef streamoff off_type;
461 typedef streampos pos_type;
462 typedef mbstate_t state_type;
463
Marshall Clow951035b2017-01-12 04:37:14 +0000464 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
465 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000466 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
467 {return __c1 == __c2;}
468 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
469 {return __c1 < __c2;}
470
Marshall Clow951035b2017-01-12 04:37:14 +0000471 static _LIBCPP_CONSTEXPR_AFTER_CXX14
472 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
473 static _LIBCPP_CONSTEXPR_AFTER_CXX14
474 size_t length(const char_type* __s) _NOEXCEPT;
475 static _LIBCPP_CONSTEXPR_AFTER_CXX14
476 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000477 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
478 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
479 {
480 return __libcpp_is_constant_evaluated()
481 ? __move_constexpr(__s1, __s2, __n)
482 : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n);
483 }
484 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
485 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000486 {
487 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkb5f44472019-11-08 13:42:26 +0000488 return __libcpp_is_constant_evaluated()
489 ? __copy_constexpr(__s1, __s2, __n)
490 : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n);
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000491 }
Michael Parkb5f44472019-11-08 13:42:26 +0000492 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
493 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
494 {
495 return __libcpp_is_constant_evaluated()
496 ? __assign_constexpr(__s, __n, __a)
497 : __n == 0 ? __s : wmemset(__s, __a, __n);
498 }
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000499 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
500 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
501 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
502 {return char_type(__c);}
503 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
504 {return int_type(__c);}
505 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
506 {return __c1 == __c2;}
507 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
508 {return int_type(WEOF);}
509};
510
Marshall Clow951035b2017-01-12 04:37:14 +0000511inline _LIBCPP_CONSTEXPR_AFTER_CXX14
512int
513char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
514{
515 if (__n == 0)
516 return 0;
Marshall Clowb344c362017-01-26 06:58:29 +0000517#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow951035b2017-01-12 04:37:14 +0000518 return __builtin_wmemcmp(__s1, __s2, __n);
519#elif _LIBCPP_STD_VER <= 14
520 return wmemcmp(__s1, __s2, __n);
521#else
522 for (; __n; --__n, ++__s1, ++__s2)
523 {
524 if (lt(*__s1, *__s2))
525 return -1;
526 if (lt(*__s2, *__s1))
527 return 1;
528 }
529 return 0;
530#endif
531}
532
Eric Fiselierd36a76c2019-09-14 19:55:28 +0000533
534template <class _Traits>
535_LIBCPP_INLINE_VISIBILITY
536_LIBCPP_CONSTEXPR
537inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
538#if _LIBCPP_DEBUG_LEVEL >= 1
539 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);
540#else
541 return _Traits::length(__s);
542#endif
543}
544
Marshall Clow951035b2017-01-12 04:37:14 +0000545inline _LIBCPP_CONSTEXPR_AFTER_CXX14
546size_t
547char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
548{
Marshall Clowb344c362017-01-26 06:58:29 +0000549#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow951035b2017-01-12 04:37:14 +0000550 return __builtin_wcslen(__s);
551#elif _LIBCPP_STD_VER <= 14
552 return wcslen(__s);
553#else
554 size_t __len = 0;
555 for (; !eq(*__s, char_type(0)); ++__s)
556 ++__len;
557 return __len;
558#endif
559}
560
561inline _LIBCPP_CONSTEXPR_AFTER_CXX14
562const wchar_t*
563char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
564{
565 if (__n == 0)
Marshall Clow32043ac2018-02-06 18:58:05 +0000566 return nullptr;
Marshall Clowb344c362017-01-26 06:58:29 +0000567#if __has_feature(cxx_constexpr_string_builtins)
Marshall Clow32043ac2018-02-06 18:58:05 +0000568 return __builtin_wmemchr(__s, __a, __n);
Marshall Clow951035b2017-01-12 04:37:14 +0000569#elif _LIBCPP_STD_VER <= 14
570 return wmemchr(__s, __a, __n);
571#else
572 for (; __n; --__n)
573 {
574 if (eq(*__s, __a))
575 return __s;
576 ++__s;
577 }
Marshall Clow32043ac2018-02-06 18:58:05 +0000578 return nullptr;
Marshall Clow951035b2017-01-12 04:37:14 +0000579#endif
580}
581
582
Marshall Clow8732fed2018-12-11 04:35:44 +0000583#ifndef _LIBCPP_NO_HAS_CHAR8_T
584
585template <>
586struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
587{
588 typedef char8_t char_type;
589 typedef unsigned int int_type;
590 typedef streamoff off_type;
591 typedef u8streampos pos_type;
592 typedef mbstate_t state_type;
593
594 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
595 {__c1 = __c2;}
596 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
597 {return __c1 == __c2;}
598 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
599 {return __c1 < __c2;}
600
601 static constexpr
602 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
603
604 static constexpr
605 size_t length(const char_type* __s) _NOEXCEPT;
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700606
Marshall Clow8732fed2018-12-11 04:35:44 +0000607 _LIBCPP_INLINE_VISIBILITY static constexpr
608 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700609
Michael Parkb5f44472019-11-08 13:42:26 +0000610 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
611 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
612 {
613 return __libcpp_is_constant_evaluated()
614 ? __move_constexpr(__s1, __s2, __n)
615 : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n);
616 }
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700617
Michael Parkb5f44472019-11-08 13:42:26 +0000618 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
619 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clow8732fed2018-12-11 04:35:44 +0000620 {
621 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
Michael Parkb5f44472019-11-08 13:42:26 +0000622 return __libcpp_is_constant_evaluated()
623 ? __copy_constexpr(__s1, __s2, __n)
624 : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
625 }
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700626
Michael Parkb5f44472019-11-08 13:42:26 +0000627 static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED
628 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
629 {
630 return __libcpp_is_constant_evaluated()
631 ? __assign_constexpr(__s, __n, __a)
632 : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);
633 }
Marshall Clow8732fed2018-12-11 04:35:44 +0000634
635 static inline constexpr int_type not_eof(int_type __c) noexcept
636 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
637 static inline constexpr char_type to_char_type(int_type __c) noexcept
638 {return char_type(__c);}
639 static inline constexpr int_type to_int_type(char_type __c) noexcept
640 {return int_type(__c);}
641 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
642 {return __c1 == __c2;}
643 static inline constexpr int_type eof() noexcept
644 {return int_type(EOF);}
645};
646
647// TODO use '__builtin_strlen' if it ever supports char8_t ??
648inline constexpr
649size_t
650char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
651{
652 size_t __len = 0;
653 for (; !eq(*__s, char_type(0)); ++__s)
654 ++__len;
655 return __len;
656}
657
658inline constexpr
659int
660char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
661{
662#if __has_feature(cxx_constexpr_string_builtins)
663 return __builtin_memcmp(__s1, __s2, __n);
664#else
665 for (; __n; --__n, ++__s1, ++__s2)
666 {
667 if (lt(*__s1, *__s2))
668 return -1;
669 if (lt(*__s2, *__s1))
670 return 1;
671 }
672 return 0;
673#endif
674}
675
676// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
677inline constexpr
678const char8_t*
679char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
680{
681 for (; __n; --__n)
682 {
683 if (eq(*__s, __a))
684 return __s;
685 ++__s;
686 }
687 return 0;
688}
689
690#endif // #_LIBCPP_NO_HAS_CHAR8_T
691
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000692#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
693
694template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000695struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000696{
697 typedef char16_t char_type;
698 typedef uint_least16_t int_type;
699 typedef streamoff off_type;
700 typedef u16streampos pos_type;
701 typedef mbstate_t state_type;
702
Marshall Clow951035b2017-01-12 04:37:14 +0000703 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
704 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000705 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
706 {return __c1 == __c2;}
707 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
708 {return __c1 < __c2;}
709
Marshall Clow951035b2017-01-12 04:37:14 +0000710 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
711 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
712 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
713 size_t length(const char_type* __s) _NOEXCEPT;
714 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
715 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000716 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000717 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000718 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000719 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000720 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000721 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000722
723 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
724 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
725 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
726 {return char_type(__c);}
727 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
728 {return int_type(__c);}
729 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
730 {return __c1 == __c2;}
731 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
732 {return int_type(0xFFFF);}
733};
734
Marshall Clow951035b2017-01-12 04:37:14 +0000735inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000736int
Marshall Clow36097db2016-07-28 04:52:02 +0000737char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000738{
739 for (; __n; --__n, ++__s1, ++__s2)
740 {
741 if (lt(*__s1, *__s2))
742 return -1;
743 if (lt(*__s2, *__s1))
744 return 1;
745 }
746 return 0;
747}
748
Marshall Clow951035b2017-01-12 04:37:14 +0000749inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000750size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000751char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000752{
753 size_t __len = 0;
754 for (; !eq(*__s, char_type(0)); ++__s)
755 ++__len;
756 return __len;
757}
758
Marshall Clow951035b2017-01-12 04:37:14 +0000759inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000760const char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000761char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000762{
763 for (; __n; --__n)
764 {
765 if (eq(*__s, __a))
766 return __s;
767 ++__s;
768 }
769 return 0;
770}
771
Michael Parkb5f44472019-11-08 13:42:26 +0000772inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000773char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000774char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000775{
Michael Parkb5f44472019-11-08 13:42:26 +0000776 if (__n == 0) return __s1;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000777 char_type* __r = __s1;
778 if (__s1 < __s2)
779 {
780 for (; __n; --__n, ++__s1, ++__s2)
781 assign(*__s1, *__s2);
782 }
783 else if (__s2 < __s1)
784 {
785 __s1 += __n;
786 __s2 += __n;
787 for (; __n; --__n)
788 assign(*--__s1, *--__s2);
789 }
790 return __r;
791}
792
Michael Parkb5f44472019-11-08 13:42:26 +0000793inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000794char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000795char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000796{
797 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
798 char_type* __r = __s1;
799 for (; __n; --__n, ++__s1, ++__s2)
800 assign(*__s1, *__s2);
801 return __r;
802}
803
Michael Parkb5f44472019-11-08 13:42:26 +0000804inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000805char16_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000806char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000807{
808 char_type* __r = __s;
809 for (; __n; --__n, ++__s)
810 assign(*__s, __a);
811 return __r;
812}
813
814template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000815struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000816{
817 typedef char32_t char_type;
818 typedef uint_least32_t int_type;
819 typedef streamoff off_type;
820 typedef u32streampos pos_type;
821 typedef mbstate_t state_type;
822
Marshall Clow951035b2017-01-12 04:37:14 +0000823 static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
824 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000825 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
826 {return __c1 == __c2;}
827 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
828 {return __c1 < __c2;}
829
Marshall Clow951035b2017-01-12 04:37:14 +0000830 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
831 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
832 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
833 size_t length(const char_type* __s) _NOEXCEPT;
834 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
835 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000836 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000837 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000838 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000839 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
Michael Parkb5f44472019-11-08 13:42:26 +0000840 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clow36097db2016-07-28 04:52:02 +0000841 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000842
843 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
844 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
845 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
846 {return char_type(__c);}
847 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
848 {return int_type(__c);}
849 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
850 {return __c1 == __c2;}
851 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
852 {return int_type(0xFFFFFFFF);}
853};
854
Marshall Clow951035b2017-01-12 04:37:14 +0000855inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000856int
Marshall Clow36097db2016-07-28 04:52:02 +0000857char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000858{
859 for (; __n; --__n, ++__s1, ++__s2)
860 {
861 if (lt(*__s1, *__s2))
862 return -1;
863 if (lt(*__s2, *__s1))
864 return 1;
865 }
866 return 0;
867}
868
Marshall Clow951035b2017-01-12 04:37:14 +0000869inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000870size_t
Marshall Clow36097db2016-07-28 04:52:02 +0000871char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000872{
873 size_t __len = 0;
874 for (; !eq(*__s, char_type(0)); ++__s)
875 ++__len;
876 return __len;
877}
878
Marshall Clow951035b2017-01-12 04:37:14 +0000879inline _LIBCPP_CONSTEXPR_AFTER_CXX14
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000880const char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000881char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000882{
883 for (; __n; --__n)
884 {
885 if (eq(*__s, __a))
886 return __s;
887 ++__s;
888 }
889 return 0;
890}
891
Michael Parkb5f44472019-11-08 13:42:26 +0000892inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000893char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000894char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000895{
Michael Parkb5f44472019-11-08 13:42:26 +0000896 if (__n == 0) return __s1;
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000897 char_type* __r = __s1;
898 if (__s1 < __s2)
899 {
900 for (; __n; --__n, ++__s1, ++__s2)
901 assign(*__s1, *__s2);
902 }
903 else if (__s2 < __s1)
904 {
905 __s1 += __n;
906 __s2 += __n;
907 for (; __n; --__n)
908 assign(*--__s1, *--__s2);
909 }
910 return __r;
911}
912
Michael Parkb5f44472019-11-08 13:42:26 +0000913inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000914char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000915char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000916{
917 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
918 char_type* __r = __s1;
919 for (; __n; --__n, ++__s1, ++__s2)
920 assign(*__s1, *__s2);
921 return __r;
922}
923
Michael Parkb5f44472019-11-08 13:42:26 +0000924inline _LIBCPP_CONSTEXPR_AFTER_CXX17
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000925char32_t*
Marshall Clow36097db2016-07-28 04:52:02 +0000926char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000927{
928 char_type* __r = __s;
929 for (; __n; --__n, ++__s)
930 assign(*__s, __a);
931 return __r;
932}
933
934#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
935
936// helper fns for basic_string and string_view
937
938// __str_find
939template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
940inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700941__str_find(const _CharT *__p, _SizeT __sz,
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000942 _CharT __c, _SizeT __pos) _NOEXCEPT
943{
944 if (__pos >= __sz)
945 return __npos;
946 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
947 if (__r == 0)
948 return __npos;
949 return static_cast<_SizeT>(__r - __p);
950}
951
Sebastian Pop65115202016-12-30 18:01:36 +0000952template <class _CharT, class _Traits>
953inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
954__search_substring(const _CharT *__first1, const _CharT *__last1,
955 const _CharT *__first2, const _CharT *__last2) {
956 // Take advantage of knowing source and pattern lengths.
957 // Stop short when source is smaller than pattern.
958 const ptrdiff_t __len2 = __last2 - __first2;
959 if (__len2 == 0)
960 return __first1;
961
962 ptrdiff_t __len1 = __last1 - __first1;
963 if (__len1 < __len2)
964 return __last1;
965
966 // First element of __first2 is loop invariant.
967 _CharT __f2 = *__first2;
968 while (true) {
969 __len1 = __last1 - __first1;
970 // Check whether __first1 still has at least __len2 bytes.
971 if (__len1 < __len2)
972 return __last1;
973
974 // Find __f2 the first byte matching in __first1.
975 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
976 if (__first1 == 0)
977 return __last1;
978
979 // It is faster to compare from the first byte of __first1 even if we
980 // already know that it matches the first byte of __first2: this is because
981 // __first2 is most likely aligned, as it is user's "pattern" string, and
982 // __first1 + 1 is most likely not aligned, as the match is in the middle of
983 // the string.
984 if (_Traits::compare(__first1, __first2, __len2) == 0)
985 return __first1;
986
987 ++__first1;
988 }
989}
990
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000991template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
992inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionnefd77e4f2019-10-23 10:40:15 -0700993__str_find(const _CharT *__p, _SizeT __sz,
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000994 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
995{
Sebastian Pop65115202016-12-30 18:01:36 +0000996 if (__pos > __sz)
Marshall Clowdf63a6d2016-07-21 05:31:24 +0000997 return __npos;
Sebastian Pop65115202016-12-30 18:01:36 +0000998
999 if (__n == 0) // There is nothing to search, just return __pos.
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001000 return __pos;
Sebastian Pop65115202016-12-30 18:01:36 +00001001
1002 const _CharT *__r = __search_substring<_CharT, _Traits>(
1003 __p + __pos, __p + __sz, __s, __s + __n);
1004
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001005 if (__r == __p + __sz)
1006 return __npos;
1007 return static_cast<_SizeT>(__r - __p);
1008}
1009
1010
1011// __str_rfind
1012
1013template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1014inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionnefd77e4f2019-10-23 10:40:15 -07001015__str_rfind(const _CharT *__p, _SizeT __sz,
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001016 _CharT __c, _SizeT __pos) _NOEXCEPT
1017{
1018 if (__sz < 1)
1019 return __npos;
1020 if (__pos < __sz)
1021 ++__pos;
1022 else
1023 __pos = __sz;
1024 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1025 {
1026 if (_Traits::eq(*--__ps, __c))
1027 return static_cast<_SizeT>(__ps - __p);
1028 }
1029 return __npos;
1030}
1031
1032template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1033inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
Louis Dionnefd77e4f2019-10-23 10:40:15 -07001034__str_rfind(const _CharT *__p, _SizeT __sz,
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001035 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1036{
1037 __pos = _VSTD::min(__pos, __sz);
1038 if (__n < __sz - __pos)
1039 __pos += __n;
1040 else
1041 __pos = __sz;
1042 const _CharT* __r = _VSTD::__find_end(
Louis Dionnefd77e4f2019-10-23 10:40:15 -07001043 __p, __p + __pos, __s, __s + __n, _Traits::eq,
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001044 random_access_iterator_tag(), random_access_iterator_tag());
1045 if (__n > 0 && __r == __p + __pos)
1046 return __npos;
1047 return static_cast<_SizeT>(__r - __p);
1048}
1049
1050// __str_find_first_of
1051template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1052inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1053__str_find_first_of(const _CharT *__p, _SizeT __sz,
1054 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1055{
1056 if (__pos >= __sz || __n == 0)
1057 return __npos;
1058 const _CharT* __r = _VSTD::__find_first_of_ce
1059 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
1060 if (__r == __p + __sz)
1061 return __npos;
1062 return static_cast<_SizeT>(__r - __p);
1063}
1064
1065
1066// __str_find_last_of
1067template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1068inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1069__str_find_last_of(const _CharT *__p, _SizeT __sz,
1070 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1071 {
1072 if (__n != 0)
1073 {
1074 if (__pos < __sz)
1075 ++__pos;
1076 else
1077 __pos = __sz;
1078 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1079 {
1080 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
1081 if (__r)
1082 return static_cast<_SizeT>(__ps - __p);
1083 }
1084 }
1085 return __npos;
1086}
1087
1088
1089// __str_find_first_not_of
1090template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1091inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1092__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1093 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1094{
1095 if (__pos < __sz)
1096 {
1097 const _CharT* __pe = __p + __sz;
1098 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1099 if (_Traits::find(__s, __n, *__ps) == 0)
1100 return static_cast<_SizeT>(__ps - __p);
1101 }
1102 return __npos;
1103}
1104
1105
1106template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1107inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1108__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1109 _CharT __c, _SizeT __pos) _NOEXCEPT
1110{
1111 if (__pos < __sz)
1112 {
1113 const _CharT* __pe = __p + __sz;
1114 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1115 if (!_Traits::eq(*__ps, __c))
1116 return static_cast<_SizeT>(__ps - __p);
1117 }
1118 return __npos;
1119}
1120
1121
1122// __str_find_last_not_of
1123template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1124inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1125__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1126 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1127{
1128 if (__pos < __sz)
1129 ++__pos;
1130 else
1131 __pos = __sz;
1132 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1133 if (_Traits::find(__s, __n, *--__ps) == 0)
1134 return static_cast<_SizeT>(__ps - __p);
1135 return __npos;
1136}
1137
1138
1139template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1140inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1141__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1142 _CharT __c, _SizeT __pos) _NOEXCEPT
1143{
1144 if (__pos < __sz)
1145 ++__pos;
1146 else
1147 __pos = __sz;
1148 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1149 if (!_Traits::eq(*--__ps, __c))
1150 return static_cast<_SizeT>(__ps - __p);
1151 return __npos;
1152}
1153
1154template<class _Ptr>
Eric Fiselier1b57fa82016-09-15 22:27:07 +00001155inline _LIBCPP_INLINE_VISIBILITY
1156size_t __do_string_hash(_Ptr __p, _Ptr __e)
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001157{
1158 typedef typename iterator_traits<_Ptr>::value_type value_type;
1159 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
1160}
1161
1162template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
1163struct __quoted_output_proxy
1164{
1165 _Iter __first;
1166 _Iter __last;
1167 _CharT __delim;
1168 _CharT __escape;
1169
1170 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
1171 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
Louis Dionnefd77e4f2019-10-23 10:40:15 -07001172 // This would be a nice place for a string_ref
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001173};
1174
1175_LIBCPP_END_NAMESPACE_STD
1176
Eric Fiselierf4433a32017-05-31 22:07:49 +00001177_LIBCPP_POP_MACROS
1178
Marshall Clowdf63a6d2016-07-21 05:31:24 +00001179#endif // _LIBCPP___STRING