diff options
author | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
commit | 60b571e49a90d38697b3aca23020d9da42fc7d7f (patch) | |
tree | 99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/libc++/include/string | |
parent | bea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff) | |
download | FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz |
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste):
Add WITH_LLD_AS_LD build knob
If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not
capable of linking the world and kernel, but can self-host and link many
substantial applications. GNU ld continues to be used for the world and
kernel build, regardless of how this knob is set.
It is on by default for arm64, and off for all other CPU architectures.
Sponsored by: The FreeBSD Foundation
MFC r310840:
Reapply 310775, now it also builds correctly if lldb is disabled:
Move llvm-objdump from CLANG_EXTRAS to installed by default
We currently install three tools from binutils 2.17.50: as, ld, and
objdump. Work is underway to migrate to a permissively-licensed
tool-chain, with one goal being the retirement of binutils 2.17.50.
LLVM's llvm-objdump is intended to be compatible with GNU objdump
although it is currently missing some options and may have formatting
differences. Enable it by default for testing and further investigation.
It may later be changed to install as /usr/bin/objdump, it becomes a
fully viable replacement.
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D8879
MFC r312855 (by emaste):
Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC
Reported by: Dan McGregor <dan.mcgregor usask.ca>
MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines
Don't check struct rtentry on FreeBSD, it is an internal kernel structure.
On other systems it may be API structure for SIOCADDRT/SIOCDELRT.
Reviewed by: emaste, dim
MFC r314152 (by jkim):
Remove an assembler flag, which is redundant since r309124. The upstream
took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE.
http://llvm.org/viewvc/llvm-project?rev=273500&view=rev
Reviewed by: dim
MFC r314564:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
4.0.0 (branches/release_40 296509). The release will follow soon.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Also note that as of 4.0.0, lld should be able to link the base system
on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5).
Though please be aware that this is work in progress.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for
their help.
Relnotes: yes
Exp-run: antoine
PR: 215969, 216008
MFC r314708:
For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
This commit is the cause of excessive compile times on skein_block.c
(and possibly other files) during kernel builds on amd64.
We never saw the problematic behavior described in this upstream commit,
so for now it is better to revert it. An upstream bug has been filed
here: https://bugs.llvm.org/show_bug.cgi?id=32142
Reported by: mjg
MFC r314795:
Reapply r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
Pull in r296992 from upstream llvm trunk (by Sanjoy Das):
[SCEV] Decrease the recursion threshold for CompareValueComplexity
Fixes PR32142.
r287232 accidentally increased the recursion threshold for
CompareValueComplexity from 2 to 32. This change reverses that
change by introducing a separate flag for CompareValueComplexity's
threshold.
The latter revision fixes the excessive compile times for skein_block.c.
MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines
Unbreak ARMv6 world.
The new compiler_rt library imported with clang 4.0.0 have several fatal
issues (non-functional __udivsi3 for example) with ARM specific instrict
functions. As temporary workaround, until upstream solve these problems,
disable all thumb[1][2] related feature.
MFC r315016:
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release.
We were already very close to the last release candidate, so this is a
pretty minor update.
Relnotes: yes
MFC r316005:
Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by
Weiming Zhao):
builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA.
Summary:
Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation
mode (-mthumb, -marm), it reflect's capability of given CPU.
Due to this:
- use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB
- use '.thumb' directive consistently in all affected files
- decorate all thumb functions using
DEFINE_COMPILERRT_THUMB_FUNCTION()
---------
Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 !
Reviewers: weimingz, rengolin, compnerd
Subscribers: aemerson, dim
Differential Revision: https://reviews.llvm.org/D30938
Discussed with: mmel
Diffstat (limited to 'contrib/libc++/include/string')
-rw-r--r-- | contrib/libc++/include/string | 1216 |
1 files changed, 452 insertions, 764 deletions
diff --git a/contrib/libc++/include/string b/contrib/libc++/include/string index 786735f..ba311ef 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,18 @@ 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); + +#ifndef _LIBCPP_CXX03_LANG + template <class = void> +#endif + _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 +907,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 +923,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 +945,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 +958,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 +977,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 +987,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 +1020,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 +1066,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 +1109,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 +1129,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 +1138,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 +1147,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 +1157,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 +1167,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 +1177,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 +1188,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 +1325,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 +1342,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 +1491,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 +1727,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 +2069,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 +2112,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 +2217,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 +2280,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 +2383,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 +2403,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 +2456,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 +2618,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 +2642,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 +2906,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 +2915,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 +3000,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 +3013,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 +3039,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 +3049,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 +3079,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 +3092,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 +3102,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 +3132,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 +3145,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 +3155,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 +3198,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 +3208,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 +3251,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 +3261,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 +3292,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 +3305,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 +3315,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 +3346,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 +3355,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 +3373,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 +3422,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 +3446,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 +3467,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 +3544,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 +3874,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 +3995,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 |