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