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