File indexing completed on 2026-05-03 08:13:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___CXX03___STRING_CHAR_TRAITS_H
0010 #define _LIBCPP___CXX03___STRING_CHAR_TRAITS_H
0011
0012 #include <__cxx03/__algorithm/fill_n.h>
0013 #include <__cxx03/__algorithm/find.h>
0014 #include <__cxx03/__algorithm/find_end.h>
0015 #include <__cxx03/__algorithm/find_first_of.h>
0016 #include <__cxx03/__algorithm/min.h>
0017 #include <__cxx03/__assert>
0018 #include <__cxx03/__compare/ordering.h>
0019 #include <__cxx03/__config>
0020 #include <__cxx03/__functional/hash.h>
0021 #include <__cxx03/__functional/identity.h>
0022 #include <__cxx03/__iterator/iterator_traits.h>
0023 #include <__cxx03/__string/constexpr_c_functions.h>
0024 #include <__cxx03/__type_traits/is_constant_evaluated.h>
0025 #include <__cxx03/__utility/is_pointer_in_range.h>
0026 #include <__cxx03/cstddef>
0027 #include <__cxx03/cstdint>
0028 #include <__cxx03/cstdio>
0029 #include <__cxx03/iosfwd>
0030
0031 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
0032 # include <__cxx03/cwchar> // for wmemcpy
0033 #endif
0034
0035 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0036 # pragma GCC system_header
0037 #endif
0038
0039 _LIBCPP_PUSH_MACROS
0040 #include <__cxx03/__undef_macros>
0041
0042 _LIBCPP_BEGIN_NAMESPACE_STD
0043
0044 template <class _CharT>
0045 struct char_traits;
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 template <>
0080 struct _LIBCPP_TEMPLATE_VIS char_traits<char> {
0081 using char_type = char;
0082 using int_type = int;
0083 using off_type = streamoff;
0084 using pos_type = streampos;
0085 using state_type = mbstate_t;
0086 #if _LIBCPP_STD_VER >= 20
0087 using comparison_category = strong_ordering;
0088 #endif
0089
0090 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
0091 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
0092 __c1 = __c2;
0093 }
0094
0095
0096 static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
0097 return __c1 == __c2;
0098 }
0099 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
0100 return (unsigned char)__c1 < (unsigned char)__c2;
0101 }
0102
0103
0104
0105 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0106 compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT {
0107 if (__libcpp_is_constant_evaluated()) {
0108 #ifdef _LIBCPP_COMPILER_CLANG_BASED
0109 return __builtin_memcmp(__lhs, __rhs, __count);
0110 #else
0111 while (__count != 0) {
0112 if (lt(*__lhs, *__rhs))
0113 return -1;
0114 if (lt(*__rhs, *__lhs))
0115 return 1;
0116
0117 __count -= sizeof(char_type);
0118 ++__lhs;
0119 ++__rhs;
0120 }
0121 return 0;
0122 #endif
0123 } else {
0124 return __builtin_memcmp(__lhs, __rhs, __count);
0125 }
0126 }
0127
0128 static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
0129 return std::__constexpr_strlen(__s);
0130 }
0131
0132 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
0133 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
0134 if (__n == 0)
0135 return nullptr;
0136 return std::__constexpr_memchr(__s, __a, __n);
0137 }
0138
0139 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0140 move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
0141 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
0142 }
0143
0144 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0145 copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
0146 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
0147 "char_traits::copy: source and destination ranges overlap");
0148 std::__constexpr_memmove(__s1, __s2, __element_count(__n));
0149 return __s1;
0150 }
0151
0152 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0153 assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
0154 std::fill_n(__s, __n, __a);
0155 return __s;
0156 }
0157
0158 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
0159 return eq_int_type(__c, eof()) ? ~eof() : __c;
0160 }
0161 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
0162 return char_type(__c);
0163 }
0164 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
0165 return int_type((unsigned char)__c);
0166 }
0167 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
0168 return __c1 == __c2;
0169 }
0170 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }
0171 };
0172
0173 template <class _CharT, class _IntT, _IntT _EOFVal>
0174 struct __char_traits_base {
0175 using char_type = _CharT;
0176 using int_type = _IntT;
0177 using off_type = streamoff;
0178 using state_type = mbstate_t;
0179 #if _LIBCPP_STD_VER >= 20
0180 using comparison_category = strong_ordering;
0181 #endif
0182
0183
0184 using pos_type = fpos<mbstate_t>;
0185
0186 _LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 void
0187 assign(char_type& __lhs, const char_type& __rhs) _NOEXCEPT {
0188 __lhs = __rhs;
0189 }
0190
0191 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq(char_type __lhs, char_type __rhs) _NOEXCEPT {
0192 return __lhs == __rhs;
0193 }
0194
0195 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt(char_type __lhs, char_type __rhs) _NOEXCEPT {
0196 return __lhs < __rhs;
0197 }
0198
0199 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0200 move(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
0201 return std::__constexpr_memmove(__dest, __src, __element_count(__n));
0202 }
0203
0204 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0205 copy(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
0206 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__dest, __dest + __n, __src),
0207 "char_traits::copy: source and destination ranges overlap");
0208 return std::__constexpr_memmove(__dest, __src, __element_count(__n));
0209 }
0210
0211 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
0212 assign(char_type* __str, size_t __n, char_type __fill_char) _NOEXCEPT {
0213 std::fill_n(__str, __n, __fill_char);
0214 return __str;
0215 }
0216
0217 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
0218 return char_type(__c);
0219 }
0220
0221 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type(__c); }
0222
0223 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __lhs, int_type __rhs) _NOEXCEPT {
0224 return __lhs == __rhs;
0225 }
0226
0227 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return _EOFVal; }
0228
0229 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
0230 return eq_int_type(__c, eof()) ? static_cast<int_type>(~eof()) : __c;
0231 }
0232 };
0233
0234
0235
0236 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
0237 template <>
0238 struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> : __char_traits_base<wchar_t, wint_t, static_cast<wint_t>(WEOF)> {
0239 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0240 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
0241 if (__n == 0)
0242 return 0;
0243 return std::__constexpr_wmemcmp(__s1, __s2, __n);
0244 }
0245
0246 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
0247 return std::__constexpr_wcslen(__s);
0248 }
0249
0250 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
0251 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
0252 if (__n == 0)
0253 return nullptr;
0254 return std::__constexpr_wmemchr(__s, __a, __n);
0255 }
0256 };
0257 #endif
0258
0259 #ifndef _LIBCPP_HAS_NO_CHAR8_T
0260
0261 template <>
0262 struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
0263 : __char_traits_base<char8_t, unsigned int, static_cast<unsigned int>(EOF)> {
0264 static _LIBCPP_HIDE_FROM_ABI constexpr int
0265 compare(const char_type* __s1, const char_type* __s2, size_t __n) noexcept {
0266 return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
0267 }
0268
0269 static _LIBCPP_HIDE_FROM_ABI constexpr size_t length(const char_type* __str) noexcept {
0270 return std::__constexpr_strlen(__str);
0271 }
0272
0273 _LIBCPP_HIDE_FROM_ABI static constexpr const char_type*
0274 find(const char_type* __s, size_t __n, const char_type& __a) noexcept {
0275 return std::__constexpr_memchr(__s, __a, __n);
0276 }
0277 };
0278
0279 #endif
0280
0281 template <>
0282 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
0283 : __char_traits_base<char16_t, uint_least16_t, static_cast<uint_least16_t>(0xFFFF)> {
0284 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0285 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
0286 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
0287
0288 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
0289 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
0290 __identity __proj;
0291 const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
0292 if (__match == __s + __n)
0293 return nullptr;
0294 return __match;
0295 }
0296 };
0297
0298 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0299 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
0300 for (; __n; --__n, ++__s1, ++__s2) {
0301 if (lt(*__s1, *__s2))
0302 return -1;
0303 if (lt(*__s2, *__s1))
0304 return 1;
0305 }
0306 return 0;
0307 }
0308
0309 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT {
0310 size_t __len = 0;
0311 for (; !eq(*__s, char_type(0)); ++__s)
0312 ++__len;
0313 return __len;
0314 }
0315
0316 template <>
0317 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
0318 : __char_traits_base<char32_t, uint_least32_t, static_cast<uint_least32_t>(0xFFFFFFFF)> {
0319 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0320 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
0321 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
0322
0323 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
0324 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
0325 __identity __proj;
0326 const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
0327 if (__match == __s + __n)
0328 return nullptr;
0329 return __match;
0330 }
0331 };
0332
0333 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0334 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
0335 for (; __n; --__n, ++__s1, ++__s2) {
0336 if (lt(*__s1, *__s2))
0337 return -1;
0338 if (lt(*__s2, *__s1))
0339 return 1;
0340 }
0341 return 0;
0342 }
0343
0344 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT {
0345 size_t __len = 0;
0346 for (; !eq(*__s, char_type(0)); ++__s)
0347 ++__len;
0348 return __len;
0349 }
0350
0351
0352
0353
0354 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0355 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0356 __str_find(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT {
0357 if (__pos >= __sz)
0358 return __npos;
0359 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
0360 if (__r == nullptr)
0361 return __npos;
0362 return static_cast<_SizeT>(__r - __p);
0363 }
0364
0365 template <class _CharT, class _Traits>
0366 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 const _CharT* __search_substring(
0367 const _CharT* __first1, const _CharT* __last1, const _CharT* __first2, const _CharT* __last2) _NOEXCEPT {
0368
0369
0370 const ptrdiff_t __len2 = __last2 - __first2;
0371 if (__len2 == 0)
0372 return __first1;
0373
0374 ptrdiff_t __len1 = __last1 - __first1;
0375 if (__len1 < __len2)
0376 return __last1;
0377
0378
0379 _CharT __f2 = *__first2;
0380 while (true) {
0381 __len1 = __last1 - __first1;
0382
0383 if (__len1 < __len2)
0384 return __last1;
0385
0386
0387 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
0388 if (__first1 == nullptr)
0389 return __last1;
0390
0391
0392
0393
0394
0395
0396 if (_Traits::compare(__first1, __first2, __len2) == 0)
0397 return __first1;
0398
0399 ++__first1;
0400 }
0401 }
0402
0403 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0404 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0405 __str_find(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0406 if (__pos > __sz)
0407 return __npos;
0408
0409 if (__n == 0)
0410 return __pos;
0411
0412 const _CharT* __r = std::__search_substring<_CharT, _Traits>(__p + __pos, __p + __sz, __s, __s + __n);
0413
0414 if (__r == __p + __sz)
0415 return __npos;
0416 return static_cast<_SizeT>(__r - __p);
0417 }
0418
0419
0420
0421 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0422 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0423 __str_rfind(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT {
0424 if (__sz < 1)
0425 return __npos;
0426 if (__pos < __sz)
0427 ++__pos;
0428 else
0429 __pos = __sz;
0430 for (const _CharT* __ps = __p + __pos; __ps != __p;) {
0431 if (_Traits::eq(*--__ps, __c))
0432 return static_cast<_SizeT>(__ps - __p);
0433 }
0434 return __npos;
0435 }
0436
0437 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0438 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0439 __str_rfind(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0440 __pos = std::min(__pos, __sz);
0441 if (__n < __sz - __pos)
0442 __pos += __n;
0443 else
0444 __pos = __sz;
0445 const _CharT* __r = std::__find_end_classic(__p, __p + __pos, __s, __s + __n, _Traits::eq);
0446 if (__n > 0 && __r == __p + __pos)
0447 return __npos;
0448 return static_cast<_SizeT>(__r - __p);
0449 }
0450
0451
0452 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0453 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0454 __str_find_first_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0455 if (__pos >= __sz || __n == 0)
0456 return __npos;
0457 const _CharT* __r = std::__find_first_of_ce(__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq);
0458 if (__r == __p + __sz)
0459 return __npos;
0460 return static_cast<_SizeT>(__r - __p);
0461 }
0462
0463
0464 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0465 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0466 __str_find_last_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0467 if (__n != 0) {
0468 if (__pos < __sz)
0469 ++__pos;
0470 else
0471 __pos = __sz;
0472 for (const _CharT* __ps = __p + __pos; __ps != __p;) {
0473 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
0474 if (__r)
0475 return static_cast<_SizeT>(__ps - __p);
0476 }
0477 }
0478 return __npos;
0479 }
0480
0481
0482 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0483 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0484 __str_find_first_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0485 if (__pos < __sz) {
0486 const _CharT* __pe = __p + __sz;
0487 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
0488 if (_Traits::find(__s, __n, *__ps) == nullptr)
0489 return static_cast<_SizeT>(__ps - __p);
0490 }
0491 return __npos;
0492 }
0493
0494 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0495 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0496 __str_find_first_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT {
0497 if (__pos < __sz) {
0498 const _CharT* __pe = __p + __sz;
0499 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
0500 if (!_Traits::eq(*__ps, __c))
0501 return static_cast<_SizeT>(__ps - __p);
0502 }
0503 return __npos;
0504 }
0505
0506
0507 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0508 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0509 __str_find_last_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT {
0510 if (__pos < __sz)
0511 ++__pos;
0512 else
0513 __pos = __sz;
0514 for (const _CharT* __ps = __p + __pos; __ps != __p;)
0515 if (_Traits::find(__s, __n, *--__ps) == nullptr)
0516 return static_cast<_SizeT>(__ps - __p);
0517 return __npos;
0518 }
0519
0520 template <class _CharT, class _SizeT, class _Traits, _SizeT __npos>
0521 inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0522 __str_find_last_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT {
0523 if (__pos < __sz)
0524 ++__pos;
0525 else
0526 __pos = __sz;
0527 for (const _CharT* __ps = __p + __pos; __ps != __p;)
0528 if (!_Traits::eq(*--__ps, __c))
0529 return static_cast<_SizeT>(__ps - __p);
0530 return __npos;
0531 }
0532
0533 template <class _Ptr>
0534 inline _LIBCPP_HIDE_FROM_ABI size_t __do_string_hash(_Ptr __p, _Ptr __e) {
0535 typedef typename iterator_traits<_Ptr>::value_type value_type;
0536 return __murmur2_or_cityhash<size_t>()(__p, (__e - __p) * sizeof(value_type));
0537 }
0538
0539 _LIBCPP_END_NAMESPACE_STD
0540
0541 _LIBCPP_POP_MACROS
0542
0543 #endif