diff options
Diffstat (limited to 'libcxx/include/string')
| -rw-r--r-- | libcxx/include/string | 2101 |
1 files changed, 1146 insertions, 955 deletions
diff --git a/libcxx/include/string b/libcxx/include/string index 3616de8a214d..bb169a82c9e7 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -95,248 +95,246 @@ public: static const size_type npos = -1; basic_string() - noexcept(is_nothrow_default_constructible<allocator_type>::value); - explicit basic_string(const allocator_type& a); - basic_string(const basic_string& str); + noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20 + explicit basic_string(const allocator_type& a); // constexpr since C++20 + basic_string(const basic_string& str); // constexpr since C++20 basic_string(basic_string&& str) - noexcept(is_nothrow_move_constructible<allocator_type>::value); + noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20 basic_string(const basic_string& str, size_type pos, - const allocator_type& a = allocator_type()); + const allocator_type& a = allocator_type()); // constexpr since C++20 basic_string(const basic_string& str, size_type pos, size_type n, - const Allocator& a = Allocator()); + const Allocator& a = Allocator()); // constexpr since C++20 template<class T> - basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 + basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20 template <class T> - explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17 - 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()); + explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20 + basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20 + basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20 basic_string(nullptr_t) = delete; // C++2b - basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); + basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20 template<class InputIterator> basic_string(InputIterator begin, InputIterator end, - const allocator_type& a = allocator_type()); - basic_string(initializer_list<value_type>, const Allocator& = Allocator()); - basic_string(const basic_string&, const Allocator&); - basic_string(basic_string&&, const Allocator&); + const allocator_type& a = allocator_type()); // constexpr since C++20 + basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20 + basic_string(const basic_string&, const Allocator&); // constexpr since C++20 + basic_string(basic_string&&, const Allocator&); // constexpr since C++20 - ~basic_string(); + ~basic_string(); // constexpr since C++20 - operator basic_string_view<charT, traits>() const noexcept; + operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20 - basic_string& operator=(const basic_string& str); + basic_string& operator=(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& operator=(const T& t); // C++17 + basic_string& operator=(const T& t); // C++17, constexpr since C++20 basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || - allocator_type::is_always_equal::value ); // C++17 - basic_string& operator=(const value_type* s); + allocator_type::is_always_equal::value ); // C++17, constexpr since C++20 + basic_string& operator=(const value_type* s); // constexpr since C++20 basic_string& operator=(nullptr_t) = delete; // C++2b - basic_string& operator=(value_type c); - basic_string& operator=(initializer_list<value_type>); + basic_string& operator=(value_type c); // constexpr since C++20 + basic_string& operator=(initializer_list<value_type>); // constexpr since C++20 - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin() noexcept; // constexpr since C++20 + const_iterator begin() const noexcept; // constexpr since C++20 + iterator end() noexcept; // constexpr since C++20 + const_iterator end() const noexcept; // constexpr since C++20 - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin() noexcept; // constexpr since C++20 + const_reverse_iterator rbegin() const noexcept; // constexpr since C++20 + reverse_iterator rend() noexcept; // constexpr since C++20 + const_reverse_iterator rend() const noexcept; // constexpr since C++20 - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const noexcept; // constexpr since C++20 + const_iterator cend() const noexcept; // constexpr since C++20 + const_reverse_iterator crbegin() const noexcept; // constexpr since C++20 + const_reverse_iterator crend() const noexcept; // constexpr since C++20 - size_type size() const noexcept; - size_type length() const noexcept; - size_type max_size() const noexcept; - size_type capacity() const noexcept; + size_type size() const noexcept; // constexpr since C++20 + size_type length() const noexcept; // constexpr since C++20 + size_type max_size() const noexcept; // constexpr since C++20 + size_type capacity() const noexcept; // constexpr since C++20 - void resize(size_type n, value_type c); - void resize(size_type n); + void resize(size_type n, value_type c); // constexpr since C++20 + void resize(size_type n); // constexpr since C++20 template<class Operation> constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 - void reserve(size_type res_arg); + void reserve(size_type res_arg); // constexpr since C++20 void reserve(); // deprecated in C++20 - void shrink_to_fit(); - void clear() noexcept; - bool empty() const noexcept; + void shrink_to_fit(); // constexpr since C++20 + void clear() noexcept; // constexpr since C++20 + bool empty() const noexcept; // constexpr since C++20 - const_reference operator[](size_type pos) const; - reference operator[](size_type pos); + const_reference operator[](size_type pos) const; // constexpr since C++20 + reference operator[](size_type pos); // constexpr since C++20 - const_reference at(size_type n) const; - reference at(size_type n); + const_reference at(size_type n) const; // constexpr since C++20 + reference at(size_type n); // constexpr since C++20 - basic_string& operator+=(const basic_string& str); + basic_string& operator+=(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& operator+=(const T& t); // C++17 - basic_string& operator+=(const value_type* s); - basic_string& operator+=(value_type c); - basic_string& operator+=(initializer_list<value_type>); + basic_string& operator+=(const T& t); // C++17, constexpr since C++20 + basic_string& operator+=(const value_type* s); // constexpr since C++20 + basic_string& operator+=(value_type c); // constexpr since C++20 + basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20 - basic_string& append(const basic_string& str); + basic_string& append(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& append(const T& t); // C++17 - basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 + basic_string& append(const T& t); // C++17, constexpr since C++20 + basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 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); + basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 + basic_string& append(const value_type* s, size_type n); // constexpr since C++20 + basic_string& append(const value_type* s); // constexpr since C++20 + basic_string& append(size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& append(InputIterator first, InputIterator last); - basic_string& append(initializer_list<value_type>); + basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20 + basic_string& append(initializer_list<value_type>); // constexpr since C++20 - void push_back(value_type c); - void pop_back(); - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; + void push_back(value_type c); // constexpr since C++20 + void pop_back(); // constexpr since C++20 + reference front(); // constexpr since C++20 + const_reference front() const; // constexpr since C++20 + reference back(); // constexpr since C++20 + const_reference back() const; // constexpr since C++20 - basic_string& assign(const basic_string& str); + basic_string& assign(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& assign(const T& t); // C++17 - basic_string& assign(basic_string&& str); - basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 + basic_string& assign(const T& t); // C++17, constexpr since C++20 + basic_string& assign(basic_string&& str); // constexpr since C++20 + basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 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); + basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 + basic_string& assign(const value_type* s, size_type n); // constexpr since C++20 + basic_string& assign(const value_type* s); // constexpr since C++20 + basic_string& assign(size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& assign(InputIterator first, InputIterator last); - basic_string& assign(initializer_list<value_type>); + basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20 + basic_string& assign(initializer_list<value_type>); // constexpr since C++20 - basic_string& insert(size_type pos1, const basic_string& str); + basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& insert(size_type pos1, const T& t); + basic_string& insert(size_type pos1, const T& t); // constexpr since C++20 basic_string& insert(size_type pos1, const basic_string& str, - size_type pos2, size_type n); + size_type pos2, size_type n); // constexpr since C++20 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); - iterator insert(const_iterator p, value_type c); - iterator insert(const_iterator p, size_type n, value_type c); + basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20 + basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20 + basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20 + basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20 + iterator insert(const_iterator p, value_type c); // constexpr since C++20 + iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - iterator insert(const_iterator p, InputIterator first, InputIterator last); - iterator insert(const_iterator p, initializer_list<value_type>); + iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20 + iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20 - basic_string& erase(size_type pos = 0, size_type n = npos); - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); + basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20 + iterator erase(const_iterator position); // constexpr since C++20 + iterator erase(const_iterator first, const_iterator last); // constexpr since C++20 - basic_string& replace(size_type pos1, size_type n1, const basic_string& str); + basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17 + basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20 basic_string& replace(size_type pos1, size_type n1, const basic_string& str, - size_type pos2, size_type n2=npos); // C++14 + size_type pos2, size_type n2=npos); // C++14, constexpr since C++20 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); + size_type pos2, size_type n); // C++17, constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17 - 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); + basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); - basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); + basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20 - size_type copy(value_type* s, size_type n, size_type pos = 0) const; - basic_string substr(size_type pos = 0, size_type n = npos) const; + size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20 + basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr since C++20 void swap(basic_string& str) noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value || - allocator_traits<allocator_type>::is_always_equal::value); // C++17 + allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20 - const value_type* c_str() const noexcept; - const value_type* data() const noexcept; - value_type* data() noexcept; // C++17 + const value_type* c_str() const noexcept; // constexpr since C++20 + const value_type* data() const noexcept; // constexpr since C++20 + value_type* data() noexcept; // C++17, constexpr since C++20 - allocator_type get_allocator() const noexcept; + allocator_type get_allocator() const noexcept; // constexpr since C++20 - size_type find(const basic_string& str, size_type pos = 0) const noexcept; + size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - 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 find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; + size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension - 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 rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - 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_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension - 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_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - 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_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension - 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; + size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - int compare(const basic_string& str) const noexcept; + int compare(const basic_string& str) const noexcept; // constexpr since C++20 template <class T> - int compare(const T& t) const noexcept; // C++17, noexcept as an extension - int compare(size_type pos1, size_type n1, const basic_string& str) const; + int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20 template <class T> - int compare(size_type pos1, size_type n1, const T& t) const; // C++17 + int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20 int compare(size_type pos1, size_type n1, const basic_string& str, - size_type pos2, size_type n2=npos) const; // C++14 + size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20 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; + size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20 + int compare(const value_type* s) const noexcept; // constexpr since C++20 + int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20 + int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20 - bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 - bool starts_with(charT c) const noexcept; // C++20 - bool starts_with(const charT* s) const; // C++20 - bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 - bool ends_with(charT c) const noexcept; // C++20 - bool ends_with(const charT* s) const; // C++20 + constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 + constexpr bool starts_with(charT c) const noexcept; // C++20 + constexpr bool starts_with(const charT* s) const; // C++20 + constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 + constexpr bool ends_with(charT c) const noexcept; // C++20 + constexpr bool ends_with(const charT* s) const; // C++20 - constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b - constexpr bool contains(charT c) const noexcept; // C++2b - constexpr bool contains(const charT* s) const; // C++2b - - bool __invariants() const; + constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b + constexpr bool contains(charT c) const noexcept; // C++2b + constexpr bool contains(const charT* s) const; // C++2b }; template<class InputIterator, @@ -349,88 +347,88 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator()) template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs); + const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); +operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); +operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); +operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); +operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; +bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT,traits,Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> void swap(basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>& rhs) - noexcept(noexcept(lhs.swap(rhs))); + noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_istream<charT, traits>& @@ -508,45 +506,80 @@ template <> struct hash<u16string>; template <> struct hash<u32string>; template <> struct hash<wstring>; -basic_string<char> operator "" s( const char *str, size_t len ); // C++14 -basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14 -basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20 -basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14 -basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14 +basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20 +basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 +constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20 +basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 +basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 } // std */ +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__algorithm/remove.h> +#include <__algorithm/remove_if.h> +#include <__assert> // all public C++ headers provide the assertion handler #include <__config> #include <__debug> -#include <__functional_base> +#include <__format/enable_insertable.h> +#include <__functional/hash.h> +#include <__functional/unary_function.h> +#include <__ios/fpos.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/reverse_iterator.h> #include <__iterator/wrap_iter.h> -#include <algorithm> -#include <compare> +#include <__memory/allocate_at_least.h> +#include <__string/char_traits.h> +#include <__string/extern_template_lists.h> +#include <__utility/auto_cast.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <__utility/unreachable.h> +#include <climits> +#include <cstdint> #include <cstdio> // EOF #include <cstdlib> #include <cstring> -#include <initializer_list> #include <iosfwd> -#include <iterator> +#include <limits> #include <memory> #include <stdexcept> #include <string_view> #include <type_traits> -#include <utility> #include <version> #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -# include <cwchar> +# include <cwchar> #endif -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -# include <cstdint> +#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES +# include <algorithm> +# include <functional> +# include <iterator> +# include <new> +# include <typeinfo> +# include <utility> +# include <vector> #endif +// standard-mandated includes + +// [iterator.range] +#include <__iterator/access.h> +#include <__iterator/data.h> +#include <__iterator/empty.h> +#include <__iterator/reverse_access.h> +#include <__iterator/size.h> + +// [string.syn] +#include <compare> +#include <initializer_list> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -555,80 +588,35 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// fpos - -template <class _StateT> -class _LIBCPP_TEMPLATE_VIS fpos -{ -private: - _StateT __st_; - streamoff __off_; -public: - _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {} - - _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;} - - _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;} - _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;} - - _LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;} - _LIBCPP_INLINE_VISIBILITY fpos operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;} - _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;} - _LIBCPP_INLINE_VISIBILITY fpos operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;} -}; - -template <class _StateT> -inline _LIBCPP_INLINE_VISIBILITY -streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) - {return streamoff(__x) - streamoff(__y);} - -template <class _StateT> -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) - {return streamoff(__x) == streamoff(__y);} - -template <class _StateT> -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) - {return streamoff(__x) != streamoff(__y);} - // basic_string template<class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) - -#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS -template <bool> -struct __basic_string_common; - -template <> -struct __basic_string_common<true> { - // Both are defined in string.cpp - _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; - _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; -}; -#endif +extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); template <class _Iter> struct __string_is_trivial_iterator : public false_type {}; @@ -647,29 +635,13 @@ struct __can_be_converted_to_string_view : public _BoolConstant< !is_convertible<const _Tp&, const _CharT*>::value > {}; -#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - -template <class _CharT, size_t = sizeof(_CharT)> -struct __padding -{ - unsigned char __xx[sizeof(_CharT)-1]; -}; - -template <class _CharT> -struct __padding<_CharT, 1> -{ -}; - -#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - #ifndef _LIBCPP_HAS_NO_CHAR8_T typedef basic_string<char8_t> u8string; #endif - -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef basic_string<char16_t> u16string; typedef basic_string<char32_t> u32string; -#endif + +struct __uninitialized_size_tag {}; template<class _CharT, class _Traits, class _Allocator> class @@ -677,14 +649,9 @@ class #ifndef _LIBCPP_HAS_NO_CHAR8_T _LIBCPP_PREFERRED_NAME(u8string) #endif -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS _LIBCPP_PREFERRED_NAME(u16string) _LIBCPP_PREFERRED_NAME(u32string) -#endif basic_string -#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS - : private __basic_string_common<true> // This base class is historical, but it needs to remain for ABI compatibility -#endif { public: typedef basic_string __self; @@ -710,10 +677,11 @@ public: typedef __wrap_iter<pointer> iterator; typedef __wrap_iter<const_pointer> const_iterator; - typedef _VSTD::reverse_iterator<iterator> reverse_iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; private: + static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits"); #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT @@ -721,62 +689,79 @@ private: { pointer __data_; size_type __size_; - size_type __cap_; + size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; + size_type __is_long_ : 1; }; -#ifdef _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x01; - static const size_type __long_mask = 0x1ul; -#else // _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x80; - static const size_type __long_mask = ~(size_type(~0) >> 1); -#endif // _LIBCPP_BIG_ENDIAN - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? (sizeof(__long) - 1)/sizeof(value_type) : 2}; struct __short { value_type __data_[__min_cap]; - struct - : __padding<value_type> - { - unsigned char __size_; - }; + unsigned char __padding_[sizeof(value_type) - 1]; + unsigned char __size_ : 7; + unsigned char __is_long_ : 1; }; +// The __endian_factor is required because the field we use to store the size +// has one fewer bit than it would if it were not a bitfield. +// +// If the LSB is used to store the short-flag in the short string representation, +// we have to multiply the size by two when it is stored and divide it by two when +// it is loaded to make sure that we always store an even number. In the long string +// representation, we can ignore this because we can assume that we always allocate +// an even amount of value_types. +// +// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. +// This does not impact the short string representation, since we never need the MSB +// for representing the size of a short string anyway. + +#ifdef _LIBCPP_BIG_ENDIAN + static const size_type __endian_factor = 2; +#else + static const size_type __endian_factor = 1; +#endif + +#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + +#ifdef _LIBCPP_BIG_ENDIAN + static const size_type __endian_factor = 1; #else + static const size_type __endian_factor = 2; +#endif + // Attribute 'packed' is used to keep the layout compatible with the + // previous definition that did not use bit fields. This is because on + // some platforms bit fields have a default size rather than the actual + // size used, e.g., it is 4 bytes on AIX. See D128285 for details. struct __long { - size_type __cap_; + struct _LIBCPP_PACKED { + size_type __is_long_ : 1; + size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; + }; size_type __size_; pointer __data_; }; -#ifdef _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x80; - static const size_type __long_mask = ~(size_type(~0) >> 1); -#else // _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x01; - static const size_type __long_mask = 0x1ul; -#endif // _LIBCPP_BIG_ENDIAN - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? (sizeof(__long) - 1)/sizeof(value_type) : 2}; struct __short { - union - { - unsigned char __size_; - value_type __lx; + struct _LIBCPP_PACKED { + unsigned char __is_long_ : 1; + unsigned char __size_ : 7; }; + char __padding_[sizeof(value_type) - 1]; value_type __data_[__min_cap]; }; #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size."); + union __ulx{__long __lx; __short __lxx;}; enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; @@ -798,25 +783,47 @@ private: __compressed_pair<__rep, allocator_type> __r_; + // Construct a string with the given allocator and enough storage to hold `__size` characters, but + // don't initialize the characters. The contents of the string, including the null terminator, must be + // initialized separately. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + if (__size > max_size()) + __throw_length_error(); + if (__fits_in_sso(__size)) { + __zero(); + __set_short_size(__size); + } else { + auto __capacity = __recommend(__size) + 1; + auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); + __begin_lifetime(__allocation, __capacity); + __set_long_cap(__capacity); + __set_long_pointer(__allocation); + __set_long_size(__size); + } + std::__debug_db_insert_c(this); + } + public: _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; - _LIBCPP_INLINE_VISIBILITY basic_string() + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); - _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value); #else _NOEXCEPT; #endif - basic_string(const basic_string& __str); - basic_string(const basic_string& __str, const allocator_type& __a); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); @@ -824,218 +831,221 @@ public: _NOEXCEPT; #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); __init(__s, traits_type::length(__s)); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, const _Allocator& __a); #if _LIBCPP_STD_VER > 20 basic_string(nullptr_t) = delete; #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c); template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c, const _Allocator& __a); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t, const allocator_type& __a); template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last); template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il, const _Allocator& __a); #endif // _LIBCPP_CXX03_LANG - inline ~basic_string(); + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string(); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } - basic_string& operator=(const basic_string& __str); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str); - template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - basic_string& operator=(const _Tp& __t) - {__self_view __sv = __t; return assign(__sv);} + template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && + !__is_same_uncvref<_Tp, basic_string>::value> > + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) { + __self_view __sv = __t; + return assign(__sv); + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} #endif - _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator=(const value_type* __s) {return assign(__s);} #if _LIBCPP_STD_VER > 20 basic_string& operator=(nullptr_t) = delete; #endif - basic_string& operator=(value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT {return iterator(this, __get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator begin() const _NOEXCEPT {return const_iterator(this, __get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end() _NOEXCEPT {return iterator(this, __get_pointer() + size());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator end() const _NOEXCEPT {return const_iterator(this, __get_pointer() + size());} -#else - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT - {return iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT - {return const_iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT - {return iterator(__get_pointer() + size());} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT - {return const_iterator(__get_pointer() + size());} -#endif // _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type size() const _NOEXCEPT {return __is_long() ? __get_long_size() : __get_short_size();} - _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();} - _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT - {return (__is_long() ? __get_long_cap() - : static_cast<size_type>(__min_cap)) - 1;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type length() const _NOEXCEPT {return size();} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type max_size() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type capacity() const _NOEXCEPT { + return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; + } - void resize(size_type __n, value_type __c); - _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} + _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n) { resize(__n, value_type()); } - void reserve(size_type __requested_capacity); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __requested_capacity); #if _LIBCPP_STD_VER > 20 template <class _Op> _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) { __resize_default_init(__n); - __erase_to_end(_VSTD::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); + __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); } #endif - _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __resize_default_init(size_type __n); + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT; - _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY - void reserve() _NOEXCEPT {shrink_to_fit();} - _LIBCPP_INLINE_VISIBILITY - void shrink_to_fit() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT; - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool empty() const _NOEXCEPT {return size() == 0;} - _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + const_reference operator[](size_type __pos) const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](size_type __pos) _NOEXCEPT; - const_reference at(size_type __n) const; - reference at(size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference at(size_type __n) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 reference at(size_type __n); - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const basic_string& __str) { + return append(__str); + } template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string >::value, basic_string& > - operator+=(const _Tp& __t) {__self_view __sv = __t; 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;} + operator+=(const _Tp& __t) { + __self_view __sv = __t; return append(__sv); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const value_type* __s) { + return append(__s); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(value_type __c) { + push_back(__c); + return *this; + } + #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t< __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); } - basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -1043,11 +1053,11 @@ public: basic_string& > 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); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(size_type __n, value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __append_default_init(size_type __n); template<class _InputIterator> @@ -1057,7 +1067,7 @@ public: __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_InputIterator __first, _InputIterator __last) { const basic_string __temp(__first, __last, __alloc()); append(__temp.data(), __temp.size()); @@ -1070,41 +1080,40 @@ public: __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - void push_back(value_type __c); - _LIBCPP_INLINE_VISIBILITY - void pop_back(); - _LIBCPP_INLINE_VISIBILITY reference front() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY reference back() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void pop_back(); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference front() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& > assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) - {*this = _VSTD::move(__str); return *this;} + {*this = std::move(__str); return *this;} #endif - basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -1112,11 +1121,11 @@ public: basic_string& > 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); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -1124,7 +1133,7 @@ public: > assign(_InputIterator __first, _InputIterator __last); template<class _ForwardIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -1132,15 +1141,15 @@ public: > assign(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos1, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1150,22 +1159,23 @@ public: { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); } template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 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); - basic_string& insert(size_type __pos, size_type __n, value_type __c); - iterator insert(const_iterator __pos, value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, size_type __n, value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -1173,7 +1183,7 @@ public: > insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); template<class _ForwardIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -1181,45 +1191,47 @@ public: > insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, initializer_list<value_type> __il) {return insert(__pos, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG - basic_string& erase(size_type __pos = 0, size_type __n = npos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __pos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& > replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); } + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 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 + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1227,14 +1239,14 @@ public: > replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -1242,16 +1254,16 @@ public: > replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) {return replace(__i1, __i2, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG - size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string substr(size_type __pos = 0, size_type __n = npos) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; @@ -1260,123 +1272,129 @@ public: __is_nothrow_swappable<allocator_type>::value); #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const value_type* c_str() const _NOEXCEPT {return data();} - _LIBCPP_INLINE_VISIBILITY - const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());} #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY) - _LIBCPP_INLINE_VISIBILITY - value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());} #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator_type get_allocator() const _NOEXCEPT {return __alloc();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 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; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 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; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const basic_string& __str) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1385,7 +1403,7 @@ public: compare(const _Tp &__t) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1393,199 +1411,243 @@ public: > compare(size_type __pos1, size_type __n1, const _Tp& __t) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 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; + _LIBCPP_CONSTEXPR_AFTER_CXX17 + 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 + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, int > 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; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const value_type* __s) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; #if _LIBCPP_STD_VER > 17 - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { return __self_view(data(), size()).starts_with(__sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept { return starts_with(__self_view(__s)); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { return __self_view(data(), size()).ends_with( __sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept { return ends_with(__self_view(__s)); } #endif #if _LIBCPP_STD_VER > 20 - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { return __self_view(data(), size()).contains(__sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return __self_view(data(), size()).contains(__c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return __self_view(data(), size()).contains(__s); } #endif - _LIBCPP_INLINE_VISIBILITY bool __invariants() const; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const; - _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY void __shrink_or_extend(size_type __target_capacity); - - _LIBCPP_INLINE_VISIBILITY - bool __is_long() const _NOEXCEPT - {return bool(__r_.first().__s.__size_ & __short_mask);} - -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE bool __dereferenceable(const const_iterator* __i) const; bool __decrementable(const const_iterator* __i) const; bool __addable(const const_iterator* __i, ptrdiff_t __n) const; bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE private: - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { - // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly - return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); + template<class _Alloc> + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs, + const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __shrink_or_extend(size_type __target_capacity); + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + bool __is_long() const _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) + return true; + return __r_.first().__s.__is_long_; } - _LIBCPP_INLINE_VISIBILITY - allocator_type& __alloc() _NOEXCEPT - {return __r_.second();} - _LIBCPP_INLINE_VISIBILITY - const allocator_type& __alloc() const _NOEXCEPT - {return __r_.second();} + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __begin_lifetime(pointer __begin, size_type __n) { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + for (size_type __i = 0; __i != __n; ++__i) + std::construct_at(std::addressof(__begin[__i])); + } +#else + (void)__begin; + (void)__n; +#endif // _LIBCPP_STD_VER > 17 + } -#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __default_init() { + __zero(); + if (__libcpp_is_constant_evaluated()) { + size_type __sz = __recommend(0) + 1; + pointer __ptr = __alloc_traits::allocate(__alloc(), __sz); + __begin_lifetime(__ptr, __sz); + __set_long_pointer(__ptr); + __set_long_cap(__sz); + __set_long_size(0); + } + } - _LIBCPP_INLINE_VISIBILITY - void __set_short_size(size_type __s) _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} -# else - {__r_.first().__s.__size_ = (unsigned char)(__s);} -# endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __deallocate_constexpr() { + if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr) + __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap()); + } - _LIBCPP_INLINE_VISIBILITY - size_type __get_short_size() const _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_ >> 1;} -# else - {return __r_.first().__s.__size_;} -# endif + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { + // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly + return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); + } -#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + template <class _ForwardIterator> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) { + size_type __sz = size(); + size_type __cap = capacity(); + value_type* __p; + if (__cap - __sz >= __n) + { + __p = std::__to_address(__get_pointer()); + size_type __n_move = __sz - __ip; + if (__n_move != 0) + traits_type::move(__p + __ip + __n, __p + __ip, __n_move); + } + else + { + __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); + __p = std::__to_address(__get_long_pointer()); + } + __sz += __n; + __set_size(__sz); + traits_type::assign(__p[__sz], value_type()); + for (__p += __ip; __first != __last; ++__p, ++__first) + traits_type::assign(*__p, *__first); - _LIBCPP_INLINE_VISIBILITY - void __set_short_size(size_type __s) _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s);} -# else - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} -# endif + return begin() + __ip; + } - _LIBCPP_INLINE_VISIBILITY - size_type __get_short_size() const _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_;} -# else - {return __r_.first().__s.__size_ >> 1;} -# endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } -#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __set_short_size(size_type __s) _NOEXCEPT { + _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); + __r_.first().__s.__size_ = __s; + __r_.first().__s.__is_long_ = false; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type __get_short_size() const _NOEXCEPT { + _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); + return __r_.first().__s.__size_; + } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_size(size_type __s) _NOEXCEPT {__r_.first().__l.__size_ = __s;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __get_long_size() const _NOEXCEPT {return __r_.first().__l.__size_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_size(size_type __s) _NOEXCEPT {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);} - _LIBCPP_INLINE_VISIBILITY - void __set_long_cap(size_type __s) _NOEXCEPT - {__r_.first().__l.__cap_ = __long_mask | __s;} - _LIBCPP_INLINE_VISIBILITY - size_type __get_long_cap() const _NOEXCEPT - {return __r_.first().__l.__cap_ & size_type(~__long_mask);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __set_long_cap(size_type __s) _NOEXCEPT { + __r_.first().__l.__cap_ = __s / __endian_factor; + __r_.first().__l.__is_long_ = true; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type __get_long_cap() const _NOEXCEPT { + return __r_.first().__l.__cap_ * __endian_factor; + } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_pointer(pointer __p) _NOEXCEPT {__r_.first().__l.__data_ = __p;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_long_pointer() _NOEXCEPT {return __r_.first().__l.__data_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_long_pointer() const _NOEXCEPT {return __r_.first().__l.__data_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_short_pointer() _NOEXCEPT {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_short_pointer() const _NOEXCEPT {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_pointer() _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_pointer() const _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY - void __zero() _NOEXCEPT - { - size_type (&__a)[__n_words] = __r_.first().__r.__words; - for (unsigned __i = 0; __i < __n_words; ++__i) - __a[__i] = 0; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __zero() _NOEXCEPT { + __r_.first() = __rep(); + } template <size_type __a> static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __align_it(size_type __s) _NOEXCEPT {return (__s + (__a-1)) & ~(__a-1);} enum {__alignment = 16}; - static _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __recommend(size_type __s) _NOEXCEPT - { - if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1; + { + if (__s < __min_cap) { + if (__libcpp_is_constant_evaluated()) + return static_cast<size_type>(__min_cap); + else + return static_cast<size_type>(__min_cap) - 1; + } size_type __guess = __align_it<sizeof(value_type) < __alignment ? __alignment/sizeof(value_type) : 1 > (__s+1) - 1; if (__guess == __min_cap) ++__guess; return __guess; - } + } - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(const value_type* __s, size_type __sz, size_type __reserve); - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(const value_type* __s, size_type __sz); - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(size_type __n, value_type __c); // Slow path for the (inlined) copy constructor for 'long' strings. @@ -1596,10 +1658,10 @@ private: // to call the __init() functions as those are marked as inline which may // result in over-aggressive inlining by the compiler, where our aim is // to only inline the fast path code directly in the ctor. - void __init_copy_ctor_external(const value_type* __s, size_type __sz); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init_copy_ctor_external(const value_type* __s, size_type __sz); template <class _InputIterator> - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value @@ -1607,15 +1669,17 @@ private: __init(_InputIterator __first, _InputIterator __last); template <class _ForwardIterator> - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > __init(_ForwardIterator __first, _ForwardIterator __last); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add = 0); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff); @@ -1624,21 +1688,21 @@ private: // have proof that the input does not alias the current instance. // For example, operator=(basic_string) performs a 'self' check. template <bool __is_short> - basic_string& __assign_no_alias(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_no_alias(const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_to_end(size_type __pos); // __erase_external_with_move is invoked for erase() invocations where // `n ~= npos`, likely requiring memory moves on the string data. - void __erase_external_with_move(size_type __pos, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_external_with_move(size_type __pos, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str) {__copy_assign_alloc(__str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str, true_type) { if (__alloc() == __str.__alloc()) @@ -1653,25 +1717,26 @@ private: else { allocator_type __a = __str.__alloc(); - pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap()); + auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); + __begin_lifetime(__allocation.ptr, __allocation.count); __clear_and_shrink(); - __alloc() = _VSTD::move(__a); - __set_long_pointer(__p); - __set_long_cap(__str.__get_long_cap()); + __alloc() = std::move(__a); + __set_long_pointer(__allocation.ptr); + __set_long_cap(__allocation.count); __set_long_size(__str.size()); } } } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 _NOEXCEPT; @@ -1680,7 +1745,7 @@ private: #endif #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __str) _NOEXCEPT_( @@ -1689,78 +1754,83 @@ private: {__move_assign_alloc(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { - __alloc() = _VSTD::move(__c.__alloc()); + __alloc() = std::move(__c.__alloc()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} - basic_string& __assign_external(const value_type* __s); - basic_string& __assign_external(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s, size_type __n); // Assigns the value in __s, guaranteed to be __n < __min_cap in length. inline basic_string& __assign_short(const value_type* __s, size_type __n) { pointer __p = __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); - traits_type::move(_VSTD::__to_address(__p), __s, __n); + traits_type::move(std::__to_address(__p), __s, __n); traits_type::assign(__p[__n], value_type()); return *this; } - _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { __set_size(__newsz); __invalidate_iterators_past(__newsz); traits_type::assign(__p[__newsz], value_type()); return *this; } - _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); - _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_iterators_past(size_type); template<class _Tp> - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __addr_in_range(_Tp&& __t) const { - const volatile void *__p = _VSTD::addressof(__t); + // assume that the ranges overlap, because we can't check during constant evaluation + if (__libcpp_is_constant_evaluated()) + return true; + const volatile void *__p = std::addressof(__t); return data() <= __p && __p <= data() + size(); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { - _VSTD::__throw_length_error("basic_string"); + std::__throw_length_error("basic_string"); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { - _VSTD::__throw_out_of_range("basic_string"); + std::__throw_out_of_range("basic_string"); } - friend basic_string operator+<>(const basic_string&, const basic_string&); - friend basic_string operator+<>(const value_type*, const basic_string&); - friend basic_string operator+<>(value_type, const basic_string&); - friend basic_string operator+<>(const basic_string&, const value_type*); - friend basic_string operator+<>(const basic_string&, value_type); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type); }; // These declarations must appear before any functions are implicitly used // so that they have the correct visibility specifier. +#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__; #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) + _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) # endif #else - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) # endif #endif +#undef _LIBCPP_DECLARE #if _LIBCPP_STD_VER >= 17 @@ -1792,22 +1862,11 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _ #endif template <class _CharT, class _Traits, class _Allocator> -inline -void -basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() -{ -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__invalidate_all(this); -#endif -} - -template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) { -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE if (!__libcpp_is_constant_evaluated()) { __c_node* __c = __get_db()->__find_c_and_lock(this); if (__c) @@ -1821,7 +1880,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type { (*__p)->__c_ = nullptr; if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); } } __get_db()->unlock(); @@ -1829,21 +1888,21 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type } #else (void)__pos; -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) : __r_(__default_init_tag(), __default_init_tag()) { - _VSTD::__debug_db_insert_c(this); - __zero(); + std::__debug_db_insert_c(this); + __default_init(); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) @@ -1852,15 +1911,18 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #endif : __r_(__default_init_tag(), __a) { - _VSTD::__debug_db_insert_c(this); - __zero(); + std::__debug_db_insert_c(this); + __default_init(); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__reserve > max_size()) __throw_length_error(); pointer __p; @@ -1871,20 +1933,24 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, } else { - size_type __cap = __recommend(__reserve); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); + __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(std::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__sz > max_size()) __throw_length_error(); pointer __p; @@ -1895,59 +1961,63 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty } else { - size_type __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); + __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(std::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } template <class _CharT, class _Traits, class _Allocator> template <class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); __init(__s, __n); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( const basic_string& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) @@ -1955,14 +2025,17 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { + if (__libcpp_is_constant_evaluated()) + __zero(); pointer __p; if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); @@ -1970,60 +2043,65 @@ void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( } else { if (__sz > max_size()) __throw_length_error(); - size_t __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap + 1); + auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); + __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); - __set_long_cap(__cap + 1); + __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); + traits_type::copy(std::__to_address(__p), __s, __sz + 1); } #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) #else _NOEXCEPT #endif - : __r_(_VSTD::move(__str.__r_)) + : __r_(std::move(__str.__r_)) { - __str.__zero(); - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated() && __is_long()) - __get_db()->swap(this, &__str); -#endif + __str.__default_init(); + std::__debug_db_insert_c(this); + if (__is_long()) + std::__debug_db_swap(this, &__str); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) { if (__str.__is_long() && __a != __str.__alloc()) // copy, not move - __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); + __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); else { - __r_.first().__r = __str.__r_.first().__r; - __str.__zero(); + if (__libcpp_is_constant_evaluated()) { + __zero(); + __r_.first().__l = __str.__r_.first().__l; + } else { + __r_.first().__r = __str.__r_.first().__r; + } + __str.__default_init(); } - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated() && __is_long()) - __get_db()->swap(this, &__str); -#endif + std::__debug_db_insert_c(this); + if (__is_long()) + std::__debug_db_swap(this, &__str); } #endif // _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__n > max_size()) __throw_length_error(); pointer __p; @@ -2034,35 +2112,38 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) } else { - size_type __cap = __recommend(__n); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); + __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); __set_long_size(__n); } - traits_type::assign(_VSTD::__to_address(__p), __n, __c); + traits_type::assign(std::__to_address(__p), __n, __c); traits_type::assign(__p[__n], value_type()); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __init(__n, __c); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a) @@ -2071,12 +2152,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st size_type __str_sz = __str.size(); if (__pos > __str_sz) __throw_out_of_range(); - __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); - _VSTD::__debug_db_insert_c(this); + __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a) : __r_(__default_init_tag(), __a) @@ -2085,11 +2166,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st if (__pos > __str_sz) __throw_out_of_range(); __init(__str.data() + __pos, __str_sz - __pos); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) : __r_(__default_init_tag(), __a) @@ -2097,38 +2179,41 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) : __r_(__default_init_tag(), __default_init_tag()) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value > basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { - __zero(); + __default_init(); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2148,13 +2233,16 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template <class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { - size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); + if (__libcpp_is_constant_evaluated()) + __zero(); + size_type __sz = static_cast<size_type>(std::distance(__first, __last)); if (__sz > max_size()) __throw_length_error(); pointer __p; @@ -2165,10 +2253,11 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For } else { - size_type __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); + __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); __set_long_size(__sz); } @@ -2192,62 +2281,60 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator, class> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator, class> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : __r_(__default_init_tag(), __a) { __init(__first, __last); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il) : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline - +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } #endif // _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::~basic_string() { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__erase_c(this); -#endif + std::__debug_db_erase_c(this); if (__is_long()) __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace (size_type __old_cap, size_type __delta_cap, size_type __old_sz, @@ -2258,23 +2345,25 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : + __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; - pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); - __invalidate_all_iterators(); + auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); + pointer __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); + std::__debug_db_invalidate_all(this); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_address(__p), - _VSTD::__to_address(__old_p), __n_copy); + traits_type::copy(std::__to_address(__p), + std::__to_address(__old_p), __n_copy); if (__n_add != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); + traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, - _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) + traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, + std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); + if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated()) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); __old_sz = __n_copy + __n_add + __sec_cp_sz; __set_long_size(__old_sz); traits_type::assign(__p[__old_sz], value_type()); @@ -2282,6 +2371,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace template <class _CharT, class _Traits, class _Allocator> void +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add) { @@ -2290,36 +2380,39 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : + __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; - pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); - __invalidate_all_iterators(); + auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); + pointer __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); + std::__debug_db_invalidate_all(this); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_address(__p), - _VSTD::__to_address(__old_p), __n_copy); + traits_type::copy(std::__to_address(__p), + std::__to_address(__old_p), __n_copy); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, - _VSTD::__to_address(__old_p) + __n_copy + __n_del, + traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, + std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) - __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); + if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap) + __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); __set_long_pointer(__p); - __set_long_cap(__cap+1); + __set_long_cap(__allocation.count); } // assign template <class _CharT, class _Traits, class _Allocator> template <bool __is_short> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( const value_type* __s, size_type __n) { - size_type __cap = __is_short ? __min_cap : __get_long_cap(); + size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); if (__n < __cap) { pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); __is_short ? __set_short_size(__n) : __set_long_size(__n); - traits_type::copy(_VSTD::__to_address(__p), __s, __n); + traits_type::copy(std::__to_address(__p), __s, __n); traits_type::assign(__p[__n], value_type()); __invalidate_iterators_past(__n); } else { @@ -2330,12 +2423,13 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_external( const value_type* __s, size_type __n) { size_type __cap = capacity(); if (__cap >= __n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::move(__p, __s, __n); return __null_terminate_at(__p, __n); } else { @@ -2346,6 +2440,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { @@ -2356,6 +2451,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_ty } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { @@ -2365,12 +2461,13 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) size_type __sz = size(); __grow_by(__cap, __n - __cap, __sz, 0, __sz); } - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); return __null_terminate_at(__p, __n); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { @@ -2392,6 +2489,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { @@ -2413,7 +2511,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value) @@ -2425,7 +2523,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, fa } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 @@ -2446,12 +2544,16 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr } __move_assign_alloc(__str); __r_.first() = __str.__r_.first(); - __str.__set_short_size(0); - traits_type::assign(__str.__get_short_pointer()[0], value_type()); + if (__libcpp_is_constant_evaluated()) { + __str.__default_init(); + } else { + __str.__set_short_size(0); + traits_type::assign(__str.__get_short_pointer()[0], value_type()); + } } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) @@ -2465,6 +2567,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2479,6 +2582,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2488,7 +2592,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For { size_type __cap = capacity(); size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? - static_cast<size_type>(_VSTD::distance(__first, __last)) : 0; + static_cast<size_type>(std::distance(__first, __last)) : 0; if (__string_is_trivial_iterator<_ForwardIterator>::value && (__cap >= __n || !__addr_in_range(*__first))) @@ -2514,17 +2618,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { size_type __sz = __str.size(); if (__pos > __sz) __throw_out_of_range(); - return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -2537,17 +2643,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p size_type __sz = __sv.size(); if (__pos > __sz) __throw_out_of_range(); - return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { return __assign_external(__s, traits_type::length(__s)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { @@ -2561,6 +2669,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) // append template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { @@ -2571,7 +2680,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty { if (__n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::copy(__p + __sz, __s, __n); __sz += __n; __set_size(__sz); @@ -2584,6 +2693,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { @@ -2594,7 +2704,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) if (__cap - __sz < __n) __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer(); - traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c); + traits_type::assign(std::__to_address(__p) + __sz, __n, __c); __sz += __n; __set_size(__sz); traits_type::assign(__p[__sz], value_type()); @@ -2603,7 +2713,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline void +_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { if (__n) @@ -2620,6 +2730,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { @@ -2641,7 +2752,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) __grow_by(__cap, 1, __sz, __sz, 0); __is_short = false; // the string is always long after __grow_by } - pointer __p; + pointer __p = __get_pointer(); if (__is_short) { __p = __get_short_pointer() + __sz; @@ -2658,6 +2769,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2668,7 +2780,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( { size_type __sz = size(); size_type __cap = capacity(); - size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); + size_type __n = static_cast<size_type>(std::distance(__first, __last)); if (__n) { if (__string_is_trivial_iterator<_ForwardIterator>::value && @@ -2692,7 +2804,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) { @@ -2700,17 +2812,19 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { size_type __sz = __str.size(); if (__pos > __sz) __throw_out_of_range(); - return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return append(__str.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -2722,10 +2836,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p size_type __sz = __sv.size(); if (__pos > __sz) __throw_out_of_range(); - return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2736,6 +2851,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) // insert template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { @@ -2744,11 +2860,18 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t if (__pos > __sz) __throw_out_of_range(); size_type __cap = capacity(); + if (__libcpp_is_constant_evaluated()) { + if (__cap - __sz >= __n) + __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s); + else + __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); + return *this; + } if (__cap - __sz >= __n) { if (__n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) { @@ -2768,6 +2891,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { @@ -2780,7 +2904,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n value_type* __p; if (__cap - __sz >= __n) { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) traits_type::move(__p + __pos + __n, __p + __pos, __n_move); @@ -2788,7 +2912,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n else { __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n, __c); __sz += __n; @@ -2800,6 +2924,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2816,6 +2941,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2823,49 +2949,27 @@ __enable_if_t > basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, - "string::insert(iterator, range) called with an iterator not" - " referring to this string"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, range) called with an iterator not referring to this string"); size_type __ip = static_cast<size_type>(__pos - begin()); - size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); - if (__n) + size_type __n = static_cast<size_type>(std::distance(__first, __last)); + if (__n == 0) + return begin() + __ip; + + if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) { - if (__string_is_trivial_iterator<_ForwardIterator>::value && - !__addr_in_range(*__first)) - { - size_type __sz = size(); - size_type __cap = capacity(); - value_type* __p; - if (__cap - __sz >= __n) - { - __p = _VSTD::__to_address(__get_pointer()); - size_type __n_move = __sz - __ip; - if (__n_move != 0) - traits_type::move(__p + __ip + __n, __p + __ip, __n_move); - } - else - { - __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); - __p = _VSTD::__to_address(__get_long_pointer()); - } - __sz += __n; - __set_size(__sz); - traits_type::assign(__p[__sz], value_type()); - for (__p += __ip; __first != __last; ++__p, (void) ++__first) - traits_type::assign(*__p, *__first); - } - else - { - const basic_string __temp(__first, __last, __alloc()); - return insert(__pos, __temp.data(), __temp.data() + __temp.size()); - } + return __insert_from_safe_copy(__n, __ip, __first, __last); + } + else + { + const basic_string __temp(__first, __last, __alloc()); + return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); } - return begin() + __ip; } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) { @@ -2873,6 +2977,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) @@ -2880,11 +2985,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ size_type __str_sz = __str.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); + return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -2897,10 +3003,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _ size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); + return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { @@ -2909,9 +3016,14 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, character) called with an iterator not" + " referring to this string"); + size_type __ip = static_cast<size_type>(__pos - begin()); size_type __sz = size(); size_type __cap = capacity(); @@ -2919,11 +3031,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty if (__cap == __sz) { __grow_by(__cap, 1, __sz, __ip, 0, 1); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } else { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __ip; if (__n_move != 0) traits_type::move(__p + __ip + 1, __p + __ip, __n_move); @@ -2935,7 +3047,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) { @@ -2950,6 +3062,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_typ // replace template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK @@ -2958,11 +3071,15 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - __n1 = _VSTD::min(__n1, __sz - __pos); + __n1 = std::min(__n1, __sz - __pos); size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + if (__libcpp_is_constant_evaluated()) { + __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s); + return *this; + } + value_type* __p = std::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -2999,18 +3116,19 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - __n1 = _VSTD::min(__n1, __sz - __pos); + __n1 = std::min(__n1, __sz - __pos); size_type __cap = capacity(); value_type* __p; if (__cap - __sz + __n1 >= __n2) { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -3021,7 +3139,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ else { __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n2, __c); return __null_terminate_at(__p, __sz - (__n1 - __n2)); @@ -3029,6 +3147,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -3042,7 +3161,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) { @@ -3050,6 +3169,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) @@ -3057,11 +3177,12 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ size_type __str_sz = __str.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); + return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -3074,10 +3195,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); + return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { @@ -3086,7 +3208,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { @@ -3095,7 +3217,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { @@ -3103,7 +3225,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { @@ -3111,7 +3233,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { @@ -3123,6 +3245,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it // 'externally instantiated' erase() implementation, called when __n != npos. // Does not check __pos against size() template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( size_type __pos, size_type __n) @@ -3130,8 +3253,8 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( if (__n) { size_type __sz = size(); - value_type* __p = _VSTD::__to_address(__get_pointer()); - __n = _VSTD::min(__n, __sz - __pos); + value_type* __p = std::__to_address(__get_pointer()); + __n = std::min(__n, __sz - __pos); size_type __n_move = __sz - __pos - __n; if (__n_move != 0) traits_type::move(__p + __pos, __p + __pos + __n, __n_move); @@ -3140,6 +3263,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { @@ -3154,7 +3278,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { @@ -3170,7 +3294,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { @@ -3186,7 +3310,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_i } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { @@ -3195,11 +3319,11 @@ basic_string<_CharT, _Traits, _Allocator>::pop_back() } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { - __invalidate_all_iterators(); + std::__debug_db_invalidate_all(this); if (__is_long()) { traits_type::assign(*__get_long_pointer(), value_type()); @@ -3213,14 +3337,15 @@ basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { - __null_terminate_at(_VSTD::__to_address(__get_pointer()), __pos); + __null_terminate_at(std::__to_address(__get_pointer()), __pos); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { @@ -3232,7 +3357,7 @@ basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline void +_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { size_type __sz = size(); @@ -3243,19 +3368,21 @@ basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT { size_type __m = __alloc_traits::max_size(__alloc()); -#ifdef _LIBCPP_BIG_ENDIAN - return (__m <= ~__long_mask ? __m : __m/2) - __alignment; -#else - return __m - __alignment; -#endif + if (__m <= std::numeric_limits<size_type>::max() / 2) { + return __m - __alignment; + } else { + bool __uses_lsb = __endian_factor == 2; + return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; + } } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { @@ -3268,7 +3395,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit if (__requested_capacity <= capacity()) return; - size_type __target_capacity = _VSTD::max(__requested_capacity, size()); + size_type __target_capacity = std::max(__requested_capacity, size()); __target_capacity = __recommend(__target_capacity); if (__target_capacity == capacity()) return; @@ -3276,7 +3403,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { @@ -3287,7 +3414,7 @@ basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { @@ -3296,7 +3423,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target pointer __new_data, __p; bool __was_long, __now_long; - if (__target_capacity == __min_cap - 1) + if (__fits_in_sso(__target_capacity)) { __was_long = true; __now_long = false; @@ -3305,15 +3432,20 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target } else { - if (__target_capacity > __cap) - __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + if (__target_capacity > __cap) { + auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); + __new_data = __allocation.ptr; + __target_capacity = __allocation.count - 1; + } else { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); + __new_data = __allocation.ptr; + __target_capacity = __allocation.count - 1; #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3325,12 +3457,13 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target return; #endif // _LIBCPP_NO_EXCEPTIONS } + __begin_lifetime(__new_data, __target_capacity + 1); __now_long = true; __was_long = __is_long(); __p = __get_pointer(); } - traits_type::copy(_VSTD::__to_address(__new_data), - _VSTD::__to_address(__p), size()+1); + traits_type::copy(std::__to_address(__new_data), + std::__to_address(__p), size()+1); if (__was_long) __alloc_traits::deallocate(__alloc(), __p, __cap+1); if (__now_long) @@ -3341,11 +3474,11 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target } else __set_short_size(__sz); - __invalidate_all_iterators(); + std::__debug_db_invalidate_all(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT { @@ -3354,7 +3487,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NO } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { @@ -3363,6 +3496,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { @@ -3372,6 +3506,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { @@ -3381,7 +3516,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT { @@ -3390,7 +3525,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT { @@ -3399,7 +3534,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT { @@ -3408,7 +3543,7 @@ basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT { @@ -3417,19 +3552,20 @@ basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - size_type __rlen = _VSTD::min(__n, __sz - __pos); + size_type __rlen = std::min(__n, __sz - __pos); traits_type::copy(__s, data() + __pos, __rlen); return __rlen; } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const { @@ -3437,7 +3573,7 @@ basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 @@ -3447,21 +3583,18 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) __is_nothrow_swappable<allocator_type>::value) #endif { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) { - if (!__is_long()) - __get_db()->__invalidate_all(this); - if (!__str.__is_long()) - __get_db()->__invalidate_all(&__str); - __get_db()->swap(this, &__str); - } -#endif + if (!__is_long()) + std::__debug_db_invalidate_all(this); + if (!__str.__is_long()) + std::__debug_db_invalidate_all(&__str); + std::__debug_db_swap(this, &__str); + _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()); - _VSTD::__swap_allocator(__alloc(), __str.__alloc()); + std::swap(__r_.first(), __str.__r_.first()); + std::__swap_allocator(__alloc(), __str.__alloc()); } // find @@ -3470,12 +3603,13 @@ template <class _Traits> struct _LIBCPP_HIDDEN __traits_eq { typedef typename _Traits::char_type char_type; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT {return _Traits::eq(__x, __y);} }; template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, @@ -3487,7 +3621,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3498,6 +3632,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3512,7 +3647,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3523,6 +3658,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT @@ -3534,6 +3670,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, // rfind template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos, @@ -3545,7 +3682,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3556,6 +3693,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3570,7 +3708,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3581,6 +3719,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT @@ -3592,6 +3731,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, // find_first_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos, @@ -3603,7 +3743,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3614,6 +3754,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3628,7 +3769,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3639,7 +3780,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3650,6 +3791,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, // find_last_of template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos, @@ -3661,7 +3803,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3672,6 +3814,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3686,7 +3829,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3697,7 +3840,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3708,6 +3851,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, // find_first_not_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos, @@ -3719,7 +3863,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3730,6 +3874,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3744,7 +3889,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3755,7 +3900,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3767,6 +3912,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, // find_last_not_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos, @@ -3778,7 +3924,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3789,6 +3935,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3803,7 +3950,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3814,7 +3961,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 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 @@ -3827,6 +3974,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3838,7 +3986,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE size_t __lhs_sz = size(); size_t __rhs_sz = __sv.size(); int __result = traits_type::compare(data(), __sv.data(), - _VSTD::min(__lhs_sz, __rhs_sz)); + std::min(__lhs_sz, __rhs_sz)); if (__result != 0) return __result; if (__lhs_sz < __rhs_sz) @@ -3849,7 +3997,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { @@ -3857,6 +4005,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) co } template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3867,8 +4016,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __sz = size(); if (__pos1 > __sz || __n2 == npos) __throw_out_of_range(); - size_type __rlen = _VSTD::min(__n1, __sz - __pos1); - int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); + size_type __rlen = std::min(__n1, __sz - __pos1); + int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); if (__r == 0) { if (__rlen < __n2) @@ -3881,6 +4030,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3895,7 +4045,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3906,6 +4056,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -3923,6 +4074,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3934,6 +4086,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { @@ -3942,6 +4095,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3954,7 +4108,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, // __invariants template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { @@ -3972,7 +4126,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const // __clear_and_shrink template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { @@ -3989,7 +4143,7 @@ basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT // operator== template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4001,7 +4155,7 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT @@ -4020,7 +4174,7 @@ operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4033,7 +4187,7 @@ operator==(const _CharT* __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4046,7 +4200,7 @@ operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4055,7 +4209,7 @@ operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4064,7 +4218,7 @@ operator!=(const _CharT* __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4075,7 +4229,7 @@ operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, // operator< template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4084,7 +4238,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4093,7 +4247,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4104,7 +4258,7 @@ operator< (const _CharT* __lhs, // operator> template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4113,7 +4267,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4122,7 +4276,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4133,7 +4287,7 @@ operator> (const _CharT* __lhs, // operator<= template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4142,7 +4296,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4151,7 +4305,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4162,7 +4316,7 @@ operator<=(const _CharT* __lhs, // operator>= template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4171,7 +4325,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4180,7 +4334,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4191,123 +4345,152 @@ operator>=(const _CharT* __lhs, // operator + template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { - basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + using _String = basic_string<_CharT, _Traits, _Allocator>; + auto __lhs_sz = __lhs.size(); + auto __rhs_sz = __rhs.size(); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) { - basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); - __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + using _String = basic_string<_CharT, _Traits, _Allocator>; + auto __lhs_sz = _Traits::length(__lhs); + auto __rhs_sz = __rhs.size(); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs, __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) { - basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); - __r.__init(&__lhs, 1, 1 + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + using _String = basic_string<_CharT, _Traits, _Allocator>; + typename _String::size_type __rhs_sz = __rhs.size(); + _String __r(__uninitialized_size_tag(), + __rhs_sz + 1, + _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::assign(__ptr, 1, __lhs); + _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); return __r; } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { - basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs, __rhs_sz); + using _String = basic_string<_CharT, _Traits, _Allocator>; + typename _String::size_type __lhs_sz = __lhs.size(); + typename _String::size_type __rhs_sz = _Traits::length(__rhs); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { - basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); - typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1); - __r.push_back(__rhs); + using _String = basic_string<_CharT, _Traits, _Allocator>; + typename _String::size_type __lhs_sz = __lhs.size(); + _String __r(__uninitialized_size_tag(), + __lhs_sz + 1, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::assign(__ptr + __lhs_sz, 1, __rhs); + _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); return __r; } #ifndef _LIBCPP_CXX03_LANG template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { - return _VSTD::move(__rhs.insert(0, __lhs)); + return std::move(__rhs.insert(0, __lhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) { - return _VSTD::move(__rhs.insert(0, __lhs)); + return std::move(__rhs.insert(0, __lhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) { __rhs.insert(__rhs.begin(), __lhs); - return _VSTD::move(__rhs); + return std::move(__rhs); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { __lhs.push_back(__rhs); - return _VSTD::move(__lhs); + return std::move(__lhs); } #endif // _LIBCPP_CXX03_LANG @@ -4315,7 +4498,7 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) // swap template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) @@ -4374,15 +4557,13 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type template <class _CharT, class _Allocator> struct _LIBCPP_TEMPLATE_VIS hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> > - : public unary_function< - basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> + : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { size_t operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { return __do_string_hash(__val.data(), __val.data() + __val.size()); } }; - template<class _CharT, class _Traits, class _Allocator> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, @@ -4399,68 +4580,68 @@ getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); #if _LIBCPP_STD_VER > 17 template <class _CharT, class _Traits, class _Allocator, class _Up> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { auto __old_size = __str.size(); - __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); + __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); return __old_size - __str.size(); } template <class _CharT, class _Traits, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { auto __old_size = __str.size(); - __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), + __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), __str.end()); return __old_size - __str.size(); } #endif -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return data() <= _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) < data() + size(); + return data() <= std::__to_address(__i->base()) && + std::__to_address(__i->base()) < data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const { - return data() < _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) <= data() + size(); + return data() < std::__to_address(__i->base()) && + std::__to_address(__i->base()) <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_address(__i->base()) + __n; + const value_type* __p = std::__to_address(__i->base()) + __n; return data() <= __p && __p <= data() + size(); } @@ -4468,11 +4649,11 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_address(__i->base()) + __n; + const value_type* __p = std::__to_address(__i->base()) + __n; return data() <= __p && __p < data() + size(); } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE #if _LIBCPP_STD_VER > 11 // Literal suffixes for basic_string [basic.string.literals] @@ -4480,14 +4661,14 @@ inline namespace literals { inline namespace string_literals { - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char> operator "" s( const char *__str, size_t __len ) { return basic_string<char> (__str, __len); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) { return basic_string<wchar_t> (__str, __len); @@ -4495,26 +4676,36 @@ inline namespace literals #endif #ifndef _LIBCPP_HAS_NO_CHAR8_T - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT { return basic_string<char8_t> (__str, __len); } #endif - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) { return basic_string<char16_t> (__str, __len); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) { return basic_string<char32_t> (__str, __len); } } // namespace string_literals } // namespace literals + +#if _LIBCPP_STD_VER > 17 +template <> +inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; +#endif +#endif + #endif _LIBCPP_END_NAMESPACE_STD |
