diff options
Diffstat (limited to 'contrib/libc++/include/string')
-rw-r--r-- | contrib/libc++/include/string | 1212 |
1 files changed, 448 insertions, 764 deletions
diff --git a/contrib/libc++/include/string b/contrib/libc++/include/string index 786735f970f8..136a5fb8949d 100644 --- a/contrib/libc++/include/string +++ b/contrib/libc++/include/string @@ -101,7 +101,10 @@ public: basic_string(const basic_string& str, size_type pos, const allocator_type& a = allocator_type()); basic_string(const basic_string& str, size_type pos, size_type n, - const Allocator& a = Allocator()); + const Allocator& a = Allocator()); + template<class T> + basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 + explicit basic_string(const basic_string_view<charT, traits> sv, const Allocator& a = Allocator()); basic_string(const value_type* s, const allocator_type& a = allocator_type()); basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); @@ -114,7 +117,10 @@ public: ~basic_string(); + operator basic_string_view<charT, traits>() const noexcept; + basic_string& operator=(const basic_string& str); + basic_string& operator=(basic_string_view<charT, traits> sv); basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || @@ -158,12 +164,16 @@ public: reference at(size_type n); basic_string& operator+=(const basic_string& str); + basic_string& operator+=(basic_string_view<charT, traits> sv); basic_string& operator+=(const value_type* s); basic_string& operator+=(value_type c); basic_string& operator+=(initializer_list<value_type>); basic_string& append(const basic_string& str); + basic_string& append(basic_string_view<charT, traits> sv); basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 + template <class T> + basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 basic_string& append(const value_type* s, size_type n); basic_string& append(const value_type* s); basic_string& append(size_type n, value_type c); @@ -179,8 +189,11 @@ public: const_reference back() const; basic_string& assign(const basic_string& str); + basic_string& assign(basic_string_view<charT, traits> sv); basic_string& assign(basic_string&& str); basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 + template <class T> + basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17 basic_string& assign(const value_type* s, size_type n); basic_string& assign(const value_type* s); basic_string& assign(size_type n, value_type c); @@ -189,8 +202,11 @@ public: basic_string& assign(initializer_list<value_type>); basic_string& insert(size_type pos1, const basic_string& str); + basic_string& insert(size_type pos1, basic_string_view<charT, traits> sv); basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n); + template <class T> + basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14 basic_string& insert(size_type pos, const value_type* s); basic_string& insert(size_type pos, size_type n, value_type c); @@ -205,12 +221,17 @@ public: iterator erase(const_iterator first, const_iterator last); basic_string& replace(size_type pos1, size_type n1, const basic_string& str); + basic_string& replace(size_type pos1, size_type n1, basic_string_view<charT, traits> sv); basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos); // C++14 + template <class T> + basic_string& replace(size_type pos1, size_type n1, const T& t, + size_type pos2, size_type n); // C++17 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); basic_string& replace(size_type pos, size_type n1, const value_type* s); basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); + basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view<charT, traits> sv); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); @@ -232,39 +253,50 @@ public: allocator_type get_allocator() const noexcept; size_type find(const basic_string& str, size_type pos = 0) const noexcept; + size_type find(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find(const value_type* s, size_type pos, size_type n) const noexcept; size_type find(const value_type* s, size_type pos = 0) const noexcept; size_type find(value_type c, size_type pos = 0) const noexcept; size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; + size_type ffind(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; size_type rfind(const value_type* s, size_type pos = npos) const noexcept; size_type rfind(value_type c, size_type pos = npos) const noexcept; size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_of(value_type c, size_type pos = npos) const noexcept; size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; int compare(const basic_string& str) const noexcept; + int compare(basic_string_view<charT, traits> sv) const noexcept; int compare(size_type pos1, size_type n1, const basic_string& str) const; + int compare(size_type pos1, size_type n1, basic_string_view<charT, traits> sv) const; int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos) const; // C++14 + template <class T> + int compare(size_type pos1, size_type n1, const T& t, + size_type pos2, size_type n2=npos) const; // C++17 int compare(const value_type* s) const noexcept; int compare(size_type pos1, size_type n1, const value_type* s) const; int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; @@ -435,6 +467,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 */ #include <__config> +#include <string_view> #include <iosfwd> #include <cstring> #include <cstdio> // For EOF. @@ -450,9 +483,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS #include <cstdint> #endif -#if defined(_LIBCPP_NO_EXCEPTIONS) -#include <cassert> -#endif #include <__undef_min_max> @@ -467,7 +497,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // fpos template <class _StateT> -class _LIBCPP_TYPE_VIS_ONLY fpos +class _LIBCPP_TEMPLATE_VIS fpos { private: _StateT __st_; @@ -501,647 +531,6 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {return streamoff(__x) != streamoff(__y);} -// char_traits - -template <class _CharT> -struct _LIBCPP_TYPE_VIS_ONLY char_traits -{ - typedef _CharT char_type; - typedef int int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} -}; - -template <class _CharT> -int -char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -template <class _CharT> -inline -size_t -char_traits<_CharT>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -template <class _CharT> -inline -const _CharT* -char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -template <class _CharT> -_CharT* -char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -template <class _CharT> -inline -_CharT* -char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -template <class _CharT> -inline -_CharT* -char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -// char_traits<char> - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char> -{ - typedef char char_type; - typedef int int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return (unsigned char)__c1 < (unsigned char)__c2;} - - static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);} - static inline size_t length(const char_type* __s) {return strlen(__s);} - static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) - {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);} - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); - } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type((unsigned char)__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} -}; - -// char_traits<wchar_t> - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t> -{ - typedef wchar_t char_type; - typedef wint_t int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);} - static inline size_t length(const char_type* __s) - {return wcslen(__s);} - static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) - {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);} - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); - } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) - {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(WEOF);} -}; - -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t> -{ - typedef char16_t char_type; - typedef uint_least16_t int_type; - typedef streamoff off_type; - typedef u16streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - _LIBCPP_INLINE_VISIBILITY - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - _LIBCPP_INLINE_VISIBILITY - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(0xFFFF);} -}; - -inline -int -char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -inline -size_t -char_traits<char16_t>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -inline -const char16_t* -char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -inline -char16_t* -char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -inline -char16_t* -char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -inline -char16_t* -char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t> -{ - typedef char32_t char_type; - typedef uint_least32_t int_type; - typedef streamoff off_type; - typedef u32streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - _LIBCPP_INLINE_VISIBILITY - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - _LIBCPP_INLINE_VISIBILITY - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(0xFFFFFFFF);} -}; - -inline -int -char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -inline -size_t -char_traits<char32_t>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -inline -const char32_t* -char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -inline -char32_t* -char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -inline -char32_t* -char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -inline -char32_t* -char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - -// helper fns for basic_string - -// __str_find -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos >= __sz) - return __npos; - const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c); - if (__r == 0) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos > __sz || __sz - __pos < __n) - return __npos; - if (__n == 0) - return __pos; - const _CharT* __r = - _VSTD::__search(__p + __pos, __p + __sz, - __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()).first; - if (__r == __p + __sz) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - - -// __str_rfind - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__sz < 1) - return __npos; - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - { - if (_Traits::eq(*--__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - __pos = _VSTD::min(__pos, __sz); - if (__n < __sz - __pos) - __pos += __n; - else - __pos = __sz; - const _CharT* __r = _VSTD::__find_end( - __p, __p + __pos, __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()); - if (__n > 0 && __r == __p + __pos) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - -// __str_find_first_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos >= __sz || __n == 0) - return __npos; - const _CharT* __r = _VSTD::__find_first_of_ce - (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq ); - if (__r == __p + __sz) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - - -// __str_find_last_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT - { - if (__n != 0) - { - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - { - const _CharT* __r = _Traits::find(__s, __n, *--__ps); - if (__r) - return static_cast<_SizeT>(__ps - __p); - } - } - return __npos; -} - - -// __str_find_first_not_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_not_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos < __sz) - { - const _CharT* __pe = __p + __sz; - for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) - if (_Traits::find(__s, __n, *__ps) == 0) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_not_of(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos < __sz) - { - const _CharT* __pe = __p + __sz; - for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) - if (!_Traits::eq(*__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - - -// __str_find_last_not_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_not_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - if (_Traits::find(__s, __n, *--__ps) == 0) - return static_cast<_SizeT>(__ps - __p); - return __npos; -} - - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_not_of(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - if (!_Traits::eq(*--__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - return __npos; -} - -template<class _Ptr> -size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e) -{ - typedef typename iterator_traits<_Ptr>::value_type value_type; - return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type)); -} - // basic_string template<class _CharT, class _Traits, class _Allocator> @@ -1166,40 +555,32 @@ basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); template <bool> -class _LIBCPP_TYPE_VIS_ONLY __basic_string_common +class _LIBCPP_TEMPLATE_VIS __basic_string_common { protected: - void __throw_length_error() const; - void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_length_error() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template <bool __b> void __basic_string_common<__b>::__throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw length_error("basic_string"); -#else - assert(!"basic_string length_error"); -#endif + _VSTD::__throw_length_error("basic_string"); } template <bool __b> void __basic_string_common<__b>::__throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("basic_string"); -#else - assert(!"basic_string out_of_range"); -#endif + _VSTD::__throw_out_of_range("basic_string"); } #ifdef _LIBCPP_MSVC #pragma warning( push ) #pragma warning( disable: 4231 ) #endif // _LIBCPP_MSVC -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>) #ifdef _LIBCPP_MSVC #pragma warning( pop ) #endif // _LIBCPP_MSVC @@ -1228,6 +609,11 @@ template <class _Iter> struct __libcpp_string_gets_noexcept_iterator : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {}; +template <class _CharT, class _Traits, class _Tp> +struct __can_be_converted_to_string_view : public _LIBCPP_BOOL_CONSTANT( + ( is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && + !is_convertible<const _Tp&, const _CharT*>::value)) {}; + #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT template <class _CharT, size_t = sizeof(_CharT)> @@ -1244,11 +630,12 @@ struct __padding<_CharT, 1> #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT template<class _CharT, class _Traits, class _Allocator> -class _LIBCPP_TYPE_VIS_ONLY basic_string +class _LIBCPP_TEMPLATE_VIS basic_string : private __basic_string_common<true> { public: typedef basic_string __self; + typedef basic_string_view<_CharT, _Traits> __self_view; typedef _Traits traits_type; typedef typename traits_type::char_type value_type; typedef _Allocator allocator_type; @@ -1404,6 +791,14 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string(const basic_string& __str, size_type __pos, const allocator_type& __a = allocator_type()); + template<class _Tp> + basic_string(const _Tp& __t, size_type __pos, size_type __n, + const allocator_type& __a = allocator_type(), + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); + _LIBCPP_INLINE_VISIBILITY explicit + basic_string(__self_view __sv); + _LIBCPP_INLINE_VISIBILITY + basic_string(__self_view __sv, const allocator_type& __a); template<class _InputIterator> _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); @@ -1417,9 +812,14 @@ public: basic_string(initializer_list<value_type> __il, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS - ~basic_string(); + inline ~basic_string(); + + _LIBCPP_INLINE_VISIBILITY + operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } basic_string& operator=(const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& operator=(__self_view __sv) {return assign(__sv);} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY basic_string& operator=(basic_string&& __str) @@ -1503,14 +903,15 @@ public: void clear() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;} - _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const; - _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos); + _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT; const_reference at(size_type __n) const; reference at(size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} + _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(__self_view __sv) {return append(__sv);} + _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;} #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);} @@ -1518,10 +919,21 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& append(const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); } basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + append(const _Tp& __t, size_type __pos, size_type __n=npos); basic_string& append(const value_type* __s, size_type __n); basic_string& append(const value_type* __s); basic_string& append(size_type __n, value_type __c); + template <class _ForwardIterator> + inline basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator); template<class _InputIterator> typename enable_if < @@ -1529,7 +941,12 @@ public: || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, basic_string& >::type - append(_InputIterator __first, _InputIterator __last); + _LIBCPP_INLINE_VISIBILITY + append(_InputIterator __first, _InputIterator __last) { + const basic_string __temp (__first, __last, __alloc()); + append(__temp.data(), __temp.size()); + return *this; + } template<class _ForwardIterator> typename enable_if < @@ -1537,7 +954,11 @@ public: && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, basic_string& >::type - append(_ForwardIterator __first, _ForwardIterator __last); + _LIBCPP_INLINE_VISIBILITY + append(_ForwardIterator __first, _ForwardIterator __last) { + return __append_forward_unsafe(__first, __last); + } + #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} @@ -1552,6 +973,8 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference back() const; _LIBCPP_INLINE_VISIBILITY + basic_string& assign(__self_view __sv) { return assign(__sv.data(), __sv.size()); } + _LIBCPP_INLINE_VISIBILITY basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -1560,6 +983,13 @@ public: {*this = _VSTD::move(str); return *this;} #endif basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + assign(const _Tp & __t, size_type pos, size_type n=npos); basic_string& assign(const value_type* __s, size_type __n); basic_string& assign(const value_type* __s); basic_string& assign(size_type __n, value_type __c); @@ -1586,6 +1016,15 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& insert(size_type __pos1, const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); } + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos); basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos); basic_string& insert(size_type __pos, const value_type* __s, size_type __n); basic_string& insert(size_type __pos, const value_type* __s); @@ -1623,13 +1062,24 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); } basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos); basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); _LIBCPP_INLINE_VISIBILITY + basic_string& replace(const_iterator __i1, const_iterator __i2, __self_view __sv) { return replace(__i1 - begin(), __i2 - __i1, __sv); } + _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); @@ -1655,9 +1105,9 @@ public: _LIBCPP_INLINE_VISIBILITY void swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT_DEBUG; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif @@ -1675,6 +1125,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1682,6 +1134,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type rfind(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1689,6 +1143,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1697,6 +1153,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1705,6 +1163,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1713,6 +1173,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1722,8 +1184,20 @@ public: _LIBCPP_INLINE_VISIBILITY int compare(const basic_string& __str) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY + int compare(__self_view __sv) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, __self_view __sv) const; + _LIBCPP_INLINE_VISIBILITY int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int + >::type + compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const; int compare(const value_type* __s) const _NOEXCEPT; int compare(size_type __pos1, size_type __n1, const value_type* __s) const; int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; @@ -1847,11 +1321,15 @@ private: __align_it<sizeof(value_type) < __alignment ? __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;} + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(const value_type* __s, size_type __sz, size_type __reserve); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(const value_type* __s, size_type __sz); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(size_type __n, value_type __c); template <class _InputIterator> + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_exactly_input_iterator<_InputIterator>::value, @@ -1860,6 +1338,7 @@ private: __init(_InputIterator __first, _InputIterator __last); template <class _ForwardIterator> + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_forward_iterator<_ForwardIterator>::value, @@ -2008,8 +1487,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ } template <class _CharT, class _Traits, class _Allocator> -void -basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) +void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, + size_type __sz, + size_type __reserve) { if (__reserve > max_size()) this->__throw_length_error(); @@ -2243,6 +1723,41 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +basic_string<_CharT, _Traits, _Allocator>::basic_string( + const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *) + : __r_(__a) +{ + __self_view __sv = __self_view(__t).substr(__pos, __n); + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv) +{ + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a) + : __r_(__a) +{ + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> typename enable_if < @@ -2550,7 +2065,7 @@ typename enable_if >::type basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); assign(__temp.data(), __temp.size()); return *this; } @@ -2593,6 +2108,23 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string<_CharT, _Traits, _Allocator>& +>::type +basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) +{ + __self_view __sv = __t; + size_type __sz = __sv.size(); + if (__pos > __sz) + this->__throw_out_of_range(); + return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); +} + + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { @@ -2681,43 +2213,46 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) traits_type::assign(*++__p, value_type()); } -template <class _CharT, class _Traits, class _Allocator> -template<class _InputIterator> -typename enable_if -< - __is_exactly_input_iterator<_InputIterator>::value - || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& ->::type -basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last) +template <class _Tp> +bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last) { - basic_string __temp (__first, __last, __alloc()); - append(__temp.data(), __temp.size()); - return *this; + return __first <= __p && __p < __last; +} + +template <class _Tp1, class _Tp2> +bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*) +{ + return false; } template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> -typename enable_if -< - __is_forward_iterator<_ForwardIterator>::value - && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& ->::type -basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) +basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe( + _ForwardIterator __first, _ForwardIterator __last) { + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "function requires a ForwardIterator"); size_type __sz = size(); size_type __cap = capacity(); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { - if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); - pointer __p = __get_pointer() + __sz; - for (; __first != __last; ++__p, ++__first) - traits_type::assign(*__p, *__first); - traits_type::assign(*__p, value_type()); - __set_size(__sz + __n); + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp (__first, __last, __alloc()); + append(__temp.data(), __temp.size()); + } + else + { + if (__cap - __sz < __n) + __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + pointer __p = __get_pointer() + __sz; + for (; __first != __last; ++__p, ++__first) + traits_type::assign(*__p, *__first); + traits_type::assign(*__p, value_type()); + __set_size(__sz + __n); + } } return *this; } @@ -2741,6 +2276,22 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string<_CharT, _Traits, _Allocator>& + >::type +basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) +{ + __self_view __sv = __t; + size_type __sz = __sv.size(); + if (__pos > __sz) + this->__throw_out_of_range(); + return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2828,7 +2379,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt "string::insert(iterator, range) called with an iterator not" " referring to this string"); #endif - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); return insert(__pos, __temp.data(), __temp.data() + __temp.size()); } @@ -2848,11 +2399,17 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward " referring to this string"); #endif size_type __ip = static_cast<size_type>(__pos - begin()); - size_type __sz = size(); - size_type __cap = capacity(); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp(__first, __last, __alloc()); + return insert(__pos, __temp.data(), __temp.data() + __temp.size()); + } + + size_type __sz = size(); + size_type __cap = capacity(); value_type* __p; if (__cap - __sz >= __n) { @@ -2895,6 +2452,23 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string<_CharT, _Traits, _Allocator>& +>::type +basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, + size_type __pos2, size_type __n) +{ + __self_view __sv = __t; + size_type __str_sz = __sv.size(); + if (__pos2 > __str_sz) + this->__throw_out_of_range(); + return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { @@ -3040,7 +2614,7 @@ typename enable_if basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { - basic_string __temp(__j1, __j2, __alloc()); + const basic_string __temp(__j1, __j2, __alloc()); return this->replace(__i1, __i2, __temp); } @@ -3064,6 +2638,23 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string<_CharT, _Traits, _Allocator>& +>::type +basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, + size_type __pos2, size_type __n2) +{ + __self_view __sv = __t; + size_type __str_sz = __sv.size(); + if (__pos2 > __str_sz) + this->__throw_out_of_range(); + return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { @@ -3311,7 +2902,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::const_reference -basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const +basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); return *(data() + __pos); @@ -3320,7 +2911,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::reference -basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) +basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); return *(__get_pointer() + __pos); @@ -3405,9 +2996,9 @@ inline _LIBCPP_INLINE_VISIBILITY void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -3418,6 +3009,10 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) __get_db()->__invalidate_all(&__str); __get_db()->swap(this, &__str); #endif + _LIBCPP_ASSERT( + __alloc_traits::propagate_on_container_swap::value || + __alloc_traits::is_always_equal::value || + __alloc() == __str.__alloc(), "swapping non-equal allocators"); _VSTD::swap(__r_.first(), __str.__r_.first()); __swap_allocator(__alloc(), __str.__alloc()); } @@ -3440,7 +3035,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3450,18 +3045,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3470,7 +3075,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3483,7 +3088,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3493,18 +3098,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::rfind(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3513,7 +3128,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3526,7 +3141,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3536,18 +3151,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_first_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_first_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3569,7 +3194,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3579,18 +3204,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_last_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_last_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3612,7 +3247,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3622,18 +3257,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3643,7 +3288,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3656,7 +3301,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3666,18 +3311,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3687,7 +3342,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3696,11 +3351,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY int -basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT +basic_string<_CharT, _Traits, _Allocator>::compare(__self_view __sv) const _NOEXCEPT { size_t __lhs_sz = size(); - size_t __rhs_sz = __str.size(); - int __result = traits_type::compare(data(), __str.data(), + size_t __rhs_sz = __sv.size(); + int __result = traits_type::compare(data(), __sv.data(), _VSTD::min(__lhs_sz, __rhs_sz)); if (__result != 0) return __result; @@ -3714,6 +3369,47 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) co template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY int +basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT +{ + return compare(__self_view(__str)); +} + +template <class _CharT, class _Traits, class _Allocator> +int +basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, + size_type __n1, + const value_type* __s, + size_type __n2) const +{ + _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); + size_type __sz = size(); + if (__pos1 > __sz || __n2 == npos) + this->__throw_out_of_range(); + size_type __rlen = _VSTD::min(__n1, __sz - __pos1); + int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); + if (__r == 0) + { + if (__rlen < __n2) + __r = -1; + else if (__rlen > __n2) + __r = 1; + } + return __r; +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +int +basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, + size_type __n1, + __self_view __sv) const +{ + return compare(__pos1, __n1, __sv.data(), __sv.size()); +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const @@ -3722,6 +3418,23 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int +>::type +basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, + size_type __n1, + const _Tp& __t, + size_type __pos2, + size_type __n2) const +{ + __self_view __sv = __t; + return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); +} + +template <class _CharT, class _Traits, class _Allocator> int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3729,11 +3442,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __pos2, size_type __n2) const { - size_type __sz = __str.size(); - if (__pos2 > __sz) - this->__throw_out_of_range(); - return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, - __sz - __pos2)); + return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } template <class _CharT, class _Traits, class _Allocator> @@ -3754,29 +3463,6 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, return compare(__pos1, __n1, __s, traits_type::length(__s)); } -template <class _CharT, class _Traits, class _Allocator> -int -basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, - size_type __n1, - const value_type* __s, - size_type __n2) const -{ - _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); - size_type __sz = size(); - if (__pos1 > __sz || __n2 == npos) - this->__throw_out_of_range(); - size_type __rlen = _VSTD::min(__n1, __sz - __pos1); - int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); - if (__r == 0) - { - if (__rlen < __n2) - __r = -1; - else if (__rlen > __n2) - __r = 1; - } - return __r; -} - // __invariants template<class _CharT, class _Traits, class _Allocator> @@ -3854,8 +3540,6 @@ operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; } -// operator!= - template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY bool @@ -4186,7 +3870,7 @@ template<class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>::npos; template<class _CharT, class _Traits, class _Allocator> -struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> > +struct _LIBCPP_TEMPLATE_VIS hash<basic_string<_CharT, _Traits, _Allocator> > : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t> { size_t @@ -4307,8 +3991,8 @@ inline namespace literals } #endif -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<wchar_t>) _LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) _LIBCPP_END_NAMESPACE_STD |