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