2 //===-------------------------- __string ----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP___STRING
12 #define _LIBCPP___STRING
20 template <class charT>
23 typedef charT char_type;
25 typedef streamoff off_type;
26 typedef streampos pos_type;
27 typedef mbstate_t state_type;
29 static void assign(char_type& c1, const char_type& c2) noexcept;
30 static constexpr bool eq(char_type c1, char_type c2) noexcept;
31 static constexpr bool lt(char_type c1, char_type c2) noexcept;
33 static int compare(const char_type* s1, const char_type* s2, size_t n);
34 static size_t length(const char_type* s);
35 static const char_type* find(const char_type* s, size_t n, const char_type& a);
36 static char_type* move(char_type* s1, const char_type* s2, size_t n);
37 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
38 static char_type* assign(char_type* s, size_t n, char_type a);
40 static constexpr int_type not_eof(int_type c) noexcept;
41 static constexpr char_type to_char_type(int_type c) noexcept;
42 static constexpr int_type to_int_type(char_type c) noexcept;
43 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
44 static constexpr int_type eof() noexcept;
47 template <> struct char_traits<char>;
48 template <> struct char_traits<wchar_t>;
55 #include <algorithm> // for search and min
56 #include <cstdio> // For EOF.
57 #include <memory> // for __murmur2_or_cityhash
59 #include <__undef_min_max>
63 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64 #pragma GCC system_header
67 _LIBCPP_BEGIN_NAMESPACE_STD
71 template <class _CharT>
72 struct _LIBCPP_TEMPLATE_VIS char_traits
74 typedef _CharT char_type;
76 typedef streamoff off_type;
77 typedef streampos pos_type;
78 typedef mbstate_t state_type;
80 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
82 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
83 {return __c1 == __c2;}
84 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
87 static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
88 _LIBCPP_INLINE_VISIBILITY
89 static size_t length(const char_type* __s);
90 _LIBCPP_INLINE_VISIBILITY
91 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
92 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
93 _LIBCPP_INLINE_VISIBILITY
94 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
95 _LIBCPP_INLINE_VISIBILITY
96 static char_type* assign(char_type* __s, size_t __n, char_type __a);
98 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
99 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
100 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
101 {return char_type(__c);}
102 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
103 {return int_type(__c);}
104 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
105 {return __c1 == __c2;}
106 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
107 {return int_type(EOF);}
110 template <class _CharT>
112 char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
114 for (; __n; --__n, ++__s1, ++__s2)
116 if (lt(*__s1, *__s2))
118 if (lt(*__s2, *__s1))
124 template <class _CharT>
127 char_traits<_CharT>::length(const char_type* __s)
130 for (; !eq(*__s, char_type(0)); ++__s)
135 template <class _CharT>
138 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
149 template <class _CharT>
151 char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
153 char_type* __r = __s1;
156 for (; __n; --__n, ++__s1, ++__s2)
157 assign(*__s1, *__s2);
159 else if (__s2 < __s1)
164 assign(*--__s1, *--__s2);
169 template <class _CharT>
172 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
174 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
175 char_type* __r = __s1;
176 for (; __n; --__n, ++__s1, ++__s2)
177 assign(*__s1, *__s2);
181 template <class _CharT>
184 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
186 char_type* __r = __s;
187 for (; __n; --__n, ++__s)
195 struct _LIBCPP_TEMPLATE_VIS char_traits<char>
197 typedef char char_type;
198 typedef int int_type;
199 typedef streamoff off_type;
200 typedef streampos pos_type;
201 typedef mbstate_t state_type;
203 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
205 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
206 {return __c1 == __c2;}
207 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
208 {return (unsigned char)__c1 < (unsigned char)__c2;}
210 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
211 {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);}
212 static inline size_t length(const char_type* __s) _NOEXCEPT {return strlen(__s);}
213 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
214 {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);}
215 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
216 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
217 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
219 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
220 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
222 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
223 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
225 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
226 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
227 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
228 {return char_type(__c);}
229 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
230 {return int_type((unsigned char)__c);}
231 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
232 {return __c1 == __c2;}
233 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
234 {return int_type(EOF);}
237 // char_traits<wchar_t>
240 struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
242 typedef wchar_t char_type;
243 typedef wint_t int_type;
244 typedef streamoff off_type;
245 typedef streampos pos_type;
246 typedef mbstate_t state_type;
248 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
250 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
251 {return __c1 == __c2;}
252 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
253 {return __c1 < __c2;}
255 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
256 {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);}
257 static inline size_t length(const char_type* __s) _NOEXCEPT
258 {return wcslen(__s);}
259 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
260 {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);}
261 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
262 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
263 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
265 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
266 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
268 static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
269 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
271 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
272 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
273 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
274 {return char_type(__c);}
275 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
276 {return int_type(__c);}
277 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
278 {return __c1 == __c2;}
279 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
280 {return int_type(WEOF);}
283 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
286 struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
288 typedef char16_t char_type;
289 typedef uint_least16_t int_type;
290 typedef streamoff off_type;
291 typedef u16streampos pos_type;
292 typedef mbstate_t state_type;
294 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
296 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
297 {return __c1 == __c2;}
298 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
299 {return __c1 < __c2;}
301 _LIBCPP_INLINE_VISIBILITY
302 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
303 _LIBCPP_INLINE_VISIBILITY
304 static size_t length(const char_type* __s) _NOEXCEPT;
305 _LIBCPP_INLINE_VISIBILITY
306 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
307 _LIBCPP_INLINE_VISIBILITY
308 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
309 _LIBCPP_INLINE_VISIBILITY
310 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
311 _LIBCPP_INLINE_VISIBILITY
312 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
314 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
315 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
316 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
317 {return char_type(__c);}
318 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
319 {return int_type(__c);}
320 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
321 {return __c1 == __c2;}
322 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
323 {return int_type(0xFFFF);}
328 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
330 for (; __n; --__n, ++__s1, ++__s2)
332 if (lt(*__s1, *__s2))
334 if (lt(*__s2, *__s1))
342 char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
345 for (; !eq(*__s, char_type(0)); ++__s)
352 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
365 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
367 char_type* __r = __s1;
370 for (; __n; --__n, ++__s1, ++__s2)
371 assign(*__s1, *__s2);
373 else if (__s2 < __s1)
378 assign(*--__s1, *--__s2);
385 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
387 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
388 char_type* __r = __s1;
389 for (; __n; --__n, ++__s1, ++__s2)
390 assign(*__s1, *__s2);
396 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
398 char_type* __r = __s;
399 for (; __n; --__n, ++__s)
405 struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
407 typedef char32_t char_type;
408 typedef uint_least32_t int_type;
409 typedef streamoff off_type;
410 typedef u32streampos pos_type;
411 typedef mbstate_t state_type;
413 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
415 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
416 {return __c1 == __c2;}
417 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
418 {return __c1 < __c2;}
420 _LIBCPP_INLINE_VISIBILITY
421 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
422 _LIBCPP_INLINE_VISIBILITY
423 static size_t length(const char_type* __s) _NOEXCEPT;
424 _LIBCPP_INLINE_VISIBILITY
425 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
426 _LIBCPP_INLINE_VISIBILITY
427 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
428 _LIBCPP_INLINE_VISIBILITY
429 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
430 _LIBCPP_INLINE_VISIBILITY
431 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
433 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
434 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
435 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
436 {return char_type(__c);}
437 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
438 {return int_type(__c);}
439 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
440 {return __c1 == __c2;}
441 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
442 {return int_type(0xFFFFFFFF);}
447 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
449 for (; __n; --__n, ++__s1, ++__s2)
451 if (lt(*__s1, *__s2))
453 if (lt(*__s2, *__s1))
461 char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
464 for (; !eq(*__s, char_type(0)); ++__s)
471 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
484 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
486 char_type* __r = __s1;
489 for (; __n; --__n, ++__s1, ++__s2)
490 assign(*__s1, *__s2);
492 else if (__s2 < __s1)
497 assign(*--__s1, *--__s2);
504 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
506 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
507 char_type* __r = __s1;
508 for (; __n; --__n, ++__s1, ++__s2)
509 assign(*__s1, *__s2);
515 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
517 char_type* __r = __s;
518 for (; __n; --__n, ++__s)
523 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
525 // helper fns for basic_string and string_view
528 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
529 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
530 __str_find(const _CharT *__p, _SizeT __sz,
531 _CharT __c, _SizeT __pos) _NOEXCEPT
535 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
538 return static_cast<_SizeT>(__r - __p);
541 template <class _CharT, class _Traits>
542 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
543 __search_substring(const _CharT *__first1, const _CharT *__last1,
544 const _CharT *__first2, const _CharT *__last2) {
545 // Take advantage of knowing source and pattern lengths.
546 // Stop short when source is smaller than pattern.
547 const ptrdiff_t __len2 = __last2 - __first2;
551 ptrdiff_t __len1 = __last1 - __first1;
555 // First element of __first2 is loop invariant.
556 _CharT __f2 = *__first2;
558 __len1 = __last1 - __first1;
559 // Check whether __first1 still has at least __len2 bytes.
563 // Find __f2 the first byte matching in __first1.
564 __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
568 // It is faster to compare from the first byte of __first1 even if we
569 // already know that it matches the first byte of __first2: this is because
570 // __first2 is most likely aligned, as it is user's "pattern" string, and
571 // __first1 + 1 is most likely not aligned, as the match is in the middle of
573 if (_Traits::compare(__first1, __first2, __len2) == 0)
580 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
581 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
582 __str_find(const _CharT *__p, _SizeT __sz,
583 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
588 if (__n == 0) // There is nothing to search, just return __pos.
591 const _CharT *__r = __search_substring<_CharT, _Traits>(
592 __p + __pos, __p + __sz, __s, __s + __n);
594 if (__r == __p + __sz)
596 return static_cast<_SizeT>(__r - __p);
602 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
603 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
604 __str_rfind(const _CharT *__p, _SizeT __sz,
605 _CharT __c, _SizeT __pos) _NOEXCEPT
613 for (const _CharT* __ps = __p + __pos; __ps != __p;)
615 if (_Traits::eq(*--__ps, __c))
616 return static_cast<_SizeT>(__ps - __p);
621 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
622 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
623 __str_rfind(const _CharT *__p, _SizeT __sz,
624 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
626 __pos = _VSTD::min(__pos, __sz);
627 if (__n < __sz - __pos)
631 const _CharT* __r = _VSTD::__find_end(
632 __p, __p + __pos, __s, __s + __n, _Traits::eq,
633 random_access_iterator_tag(), random_access_iterator_tag());
634 if (__n > 0 && __r == __p + __pos)
636 return static_cast<_SizeT>(__r - __p);
639 // __str_find_first_of
640 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
641 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
642 __str_find_first_of(const _CharT *__p, _SizeT __sz,
643 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
645 if (__pos >= __sz || __n == 0)
647 const _CharT* __r = _VSTD::__find_first_of_ce
648 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
649 if (__r == __p + __sz)
651 return static_cast<_SizeT>(__r - __p);
655 // __str_find_last_of
656 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
657 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
658 __str_find_last_of(const _CharT *__p, _SizeT __sz,
659 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
667 for (const _CharT* __ps = __p + __pos; __ps != __p;)
669 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
671 return static_cast<_SizeT>(__ps - __p);
678 // __str_find_first_not_of
679 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
680 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
681 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
682 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
686 const _CharT* __pe = __p + __sz;
687 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
688 if (_Traits::find(__s, __n, *__ps) == 0)
689 return static_cast<_SizeT>(__ps - __p);
695 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
696 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
697 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
698 _CharT __c, _SizeT __pos) _NOEXCEPT
702 const _CharT* __pe = __p + __sz;
703 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
704 if (!_Traits::eq(*__ps, __c))
705 return static_cast<_SizeT>(__ps - __p);
711 // __str_find_last_not_of
712 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
713 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
714 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
715 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
721 for (const _CharT* __ps = __p + __pos; __ps != __p;)
722 if (_Traits::find(__s, __n, *--__ps) == 0)
723 return static_cast<_SizeT>(__ps - __p);
728 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
729 inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
730 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
731 _CharT __c, _SizeT __pos) _NOEXCEPT
737 for (const _CharT* __ps = __p + __pos; __ps != __p;)
738 if (!_Traits::eq(*--__ps, __c))
739 return static_cast<_SizeT>(__ps - __p);
744 inline _LIBCPP_INLINE_VISIBILITY
745 size_t __do_string_hash(_Ptr __p, _Ptr __e)
747 typedef typename iterator_traits<_Ptr>::value_type value_type;
748 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
751 template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
752 struct __quoted_output_proxy
759 __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
760 : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
761 // This would be a nice place for a string_ref
764 _LIBCPP_END_NAMESPACE_STD
766 #endif // _LIBCPP___STRING