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