diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -106,7 +106,7 @@ "`P0645 `__","LWG","Text Formatting","Cologne","|In Progress|","" "`P0660 `__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","","" "`P0784 `__","CWG","More constexpr containers","Cologne","|Complete|","12.0" -"`P0980 `__","LWG","Making std::string constexpr","Cologne","","" +"`P0980 `__","LWG","Making std::string constexpr","Cologne","|In Progress|","" "`P1004 `__","LWG","Making std::vector constexpr","Cologne","","" "`P1035 `__","LWG","Input Range Adaptors","Cologne","","" "`P1065 `__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0" diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h --- a/libcxx/include/__memory/compressed_pair.h +++ b/libcxx/include/__memory/compressed_pair.h @@ -58,10 +58,8 @@ : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {} #endif - - _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; } - _LIBCPP_INLINE_VISIBILITY - const_reference __get() const _NOEXCEPT { return __value_; } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reference __get() _NOEXCEPT { return __value_; } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return __value_; } private: _Tp __value_; @@ -97,9 +95,8 @@ : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {} #endif - _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; } - _LIBCPP_INLINE_VISIBILITY - const_reference __get() const _NOEXCEPT { return *this; } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reference __get() _NOEXCEPT { return *this; } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return *this; } }; template @@ -143,23 +140,19 @@ typename __make_tuple_indices::type()) {} #endif - _LIBCPP_INLINE_VISIBILITY - typename _Base1::reference first() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base1::reference first() _NOEXCEPT { return static_cast<_Base1&>(*this).__get(); } - _LIBCPP_INLINE_VISIBILITY - typename _Base1::const_reference first() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base1::const_reference first() const _NOEXCEPT { return static_cast<_Base1 const&>(*this).__get(); } - _LIBCPP_INLINE_VISIBILITY - typename _Base2::reference second() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base2::reference second() _NOEXCEPT { return static_cast<_Base2&>(*this).__get(); } - _LIBCPP_INLINE_VISIBILITY - typename _Base2::const_reference second() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base2::const_reference second() const _NOEXCEPT { return static_cast<_Base2 const&>(*this).__get(); } diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -519,6 +519,7 @@ #include <__debug> #include <__functional_base> #include <__iterator/wrap_iter.h> +#include <__memory/construct_at.h> #include #include #include // EOF @@ -589,24 +590,28 @@ // basic_string template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); @@ -617,7 +622,7 @@ { protected: _LIBCPP_NORETURN void __throw_length_error() const; - _LIBCPP_NORETURN void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template @@ -806,21 +811,25 @@ _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; - _LIBCPP_INLINE_VISIBILITY basic_string() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string() _NOEXCEPT_(is_nothrow_default_constructible::value); - _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + explicit basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible::value); #else _NOEXCEPT; #endif + _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible::value); @@ -828,12 +837,12 @@ _NOEXCEPT; #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG template ::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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)); @@ -843,80 +852,84 @@ } template ::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c); template ::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()); template::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::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::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::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last); template::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il, const _Allocator& __a); #endif // _LIBCPP_CXX03_LANG - inline ~basic_string(); + _LIBCPP_CONSTEXPR_AFTER_CXX17 inline ~basic_string(); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str); template ::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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(initializer_list __il) {return assign(__il.begin(), __il.size());} #endif - _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);} + _LIBCPP_INLINE_VISIBILITY _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 @@ -932,106 +945,118 @@ const_iterator end() const _NOEXCEPT {return const_iterator(this, __get_pointer() + size());} #else - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT {return iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator begin() const _NOEXCEPT {return const_iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end() _NOEXCEPT {return iterator(__get_pointer() + size());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator end() const _NOEXCEPT {return const_iterator(__get_pointer() + size());} #endif // _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _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 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type length() const _NOEXCEPT {return size();} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type max_size() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type capacity() const _NOEXCEPT {return (__is_long() ? __get_long_cap() : static_cast(__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_INLINE_VISIBILITY _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); _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY void reserve() _NOEXCEPT {shrink_to_fit();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT; - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + const_reference operator[](size_type __pos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator+=(const basic_string& __str) {return append(__str);} template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator+=(const value_type* __s) {return append(__s);} + _LIBCPP_INLINE_VISIBILITY _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 __il) {return append(__il);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator+=(initializer_list __il) {return append(__il);} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str); template - _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()); } + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); template - _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 @@ -1039,8 +1064,11 @@ basic_string& > append(const _Tp& __t, size_type __pos, size_type __n=npos); + _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 @@ -1053,7 +1081,7 @@ __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_InputIterator __first, _InputIterator __last) { const basic_string __temp(__first, __last, __alloc()); append(__temp.data(), __temp.size()); @@ -1066,41 +1094,46 @@ __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(initializer_list __il) {return append(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - void push_back(value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + reference front() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + const_reference front() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + reference back() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + const_reference back() const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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;} #endif + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); template - _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 @@ -1108,11 +1141,14 @@ basic_string& > assign(const _Tp & __t, size_type __pos, size_type __n=npos); + _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 - _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, @@ -1120,7 +1156,7 @@ > assign(_InputIterator __first, _InputIterator __last); template - _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, @@ -1128,15 +1164,15 @@ > assign(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(initializer_list __il) {return assign(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos1, const basic_string& __str); template - _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, @@ -1146,22 +1182,27 @@ { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); } template - _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); + _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_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, size_type __n, value_type __c); template - _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, @@ -1169,7 +1210,7 @@ > insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); template - _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, @@ -1177,45 +1218,49 @@ > insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, initializer_list __il) {return insert(__pos, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG - + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __pos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); template - _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 - _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); + _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_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); template - _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, @@ -1223,14 +1268,14 @@ > 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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c); template - _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, @@ -1238,16 +1283,17 @@ > replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list __il) {return replace(__i1, __i2, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string substr(size_type __pos = 0, size_type __n = npos) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; @@ -1256,123 +1302,131 @@ __is_nothrow_swappable::value); #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const value_type* c_str() const _NOEXCEPT {return data();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY) - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator_type get_allocator() const _NOEXCEPT {return __alloc();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const value_type* __s, 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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const value_type* __s, 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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template - _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const basic_string& __str) const _NOEXCEPT; template - _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, @@ -1381,7 +1435,7 @@ compare(const _Tp &__t) const _NOEXCEPT; template - _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, @@ -1389,20 +1443,24 @@ > compare(size_type __pos1, size_type __n1, const _Tp& __t) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const basic_string& __str) 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 - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _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; + _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 @@ -1445,15 +1503,20 @@ { return __self_view(data(), size()).contains(__s); } #endif - _LIBCPP_INLINE_VISIBILITY bool __invariants() const; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const; - _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY void __shrink_or_extend(size_type __target_capacity); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __shrink_or_extend(size_type __target_capacity); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_long() const _NOEXCEPT - {return bool(__r_.first().__s.__size_ & __short_mask);} + { + if (__libcpp_is_constant_evaluated()) + return true; + return bool(__r_.first().__s.__size_ & __short_mask); + } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -1465,10 +1528,10 @@ #endif // _LIBCPP_DEBUG_LEVEL == 2 private: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator_type& __alloc() _NOEXCEPT {return __r_.second();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const allocator_type& __alloc() const _NOEXCEPT {return __r_.second();} @@ -1510,30 +1573,30 @@ #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_size(size_type __s) _NOEXCEPT {__r_.first().__l.__size_ = __s;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __get_long_size() const _NOEXCEPT {return __r_.first().__l.__size_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_cap(size_type __s) _NOEXCEPT {__r_.first().__l.__cap_ = __long_mask | __s;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __get_long_cap() const _NOEXCEPT {return __r_.first().__l.__cap_ & size_type(~__long_mask);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_pointer(pointer __p) _NOEXCEPT {__r_.first().__l.__data_ = __p;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_long_pointer() _NOEXCEPT {return __r_.first().__l.__data_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_long_pointer() const _NOEXCEPT {return __r_.first().__l.__data_;} _LIBCPP_INLINE_VISIBILITY @@ -1542,41 +1605,48 @@ _LIBCPP_INLINE_VISIBILITY const_pointer __get_short_pointer() const _NOEXCEPT {return pointer_traits::pointer_to(__r_.first().__s.__data_[0]);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_pointer() _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_pointer() const _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __zero() _NOEXCEPT + { + size_type (&__a)[__n_words] = __r_.first().__r.__words; + if (__libcpp_is_constant_evaluated()) { - size_type (&__a)[__n_words] = __r_.first().__r.__words; - for (unsigned __i = 0; __i < __n_words; ++__i) - __a[__i] = 0; + __r_.first() = __rep(); + return; } + for (unsigned __i = 0; __i < __n_words; ++__i) + __a[__i] = 0; + } template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __recommend(size_type __s) _NOEXCEPT - { + { + if (__libcpp_is_constant_evaluated()) + return __s + 1; if (__s < __min_cap) return static_cast(__min_cap) - 1; size_type __guess = __align_it (__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. @@ -1587,10 +1657,11 @@ // 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. + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init_copy_ctor_external(const value_type* __s, size_type __sz); template - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value @@ -1598,15 +1669,17 @@ __init(_InputIterator __first, _InputIterator __last); template - 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); @@ -1615,21 +1688,25 @@ // have proof that the input does not alias the current instance. // For example, operator=(basic_string) performs a 'self' check. template + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_no_alias(const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_to_end(size_type __pos); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __finish_replace(size_type& __sz, size_type& __n1, size_type& __n2, value_type*& __p); + // __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_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str) {__copy_assign_alloc(__str, integral_constant());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str, true_type) { if (__alloc() == __str.__alloc()) @@ -1645,6 +1722,7 @@ { allocator_type __a = __str.__alloc(); pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap()); + __begin_lifetime(__p, __str.__get_long_cap()); __clear_and_shrink(); __alloc() = _VSTD::move(__a); __set_long_pointer(__p); @@ -1654,15 +1732,15 @@ } } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 _NOEXCEPT; @@ -1671,7 +1749,7 @@ #endif #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __str) _NOEXCEPT_( @@ -1680,19 +1758,20 @@ {__move_assign_alloc(__str, integral_constant());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value) { __alloc() = _VSTD::move(__c.__alloc()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} 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. @@ -1705,8 +1784,10 @@ return *this; } - _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); - _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __invalidate_all_iterators(); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __invalidate_iterators_past(size_type); template _LIBCPP_INLINE_VISIBILITY @@ -1724,7 +1805,7 @@ #endif } - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI + _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __throw_out_of_range() const { #ifndef _LIBCPP_NO_EXCEPTIONS __basic_string_common::__throw_out_of_range(); @@ -1733,11 +1814,26 @@ #endif } - 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); + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR void __begin_lifetime(pointer __p, size_t __count) + { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) + { + for (size_t __i = 0; __i < __count; ++__i) + construct_at(&__p[__i], value_type()); + } +#else + ((void)__p); + ((void)__count); +#endif + } + + 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 @@ -1780,7 +1876,7 @@ #endif template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() { @@ -1790,7 +1886,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) { @@ -1818,7 +1914,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible::value) : __r_(__default_init_tag(), __default_init_tag()) @@ -1826,11 +1922,14 @@ #if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->__insert_c(this); #endif - __zero(); + if (__libcpp_is_constant_evaluated()) + __init(size_type(), value_type()); + else + __zero(); } template -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::value) @@ -1842,18 +1941,24 @@ #if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->__insert_c(this); #endif - __zero(); + if (__libcpp_is_constant_evaluated()) + __init(size_type(0), value_type()); + else + __zero(); } template +_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()) this->__throw_length_error(); pointer __p; - if (__reserve < __min_cap) + if (__reserve < __min_cap && !__libcpp_is_constant_evaluated()) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1862,6 +1967,7 @@ { size_type __cap = __recommend(__reserve); __p = __alloc_traits::allocate(__alloc(), __cap+1); + __begin_lifetime(__p, __cap + 1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__sz); @@ -1871,31 +1977,16 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { - if (__sz > max_size()) - this->__throw_length_error(); - pointer __p; - if (__sz < __min_cap) - { - __set_short_size(__sz); - __p = __get_short_pointer(); - } - else - { - size_type __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap+1); - __set_long_pointer(__p); - __set_long_cap(__cap+1); - __set_long_size(__sz); - } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); - traits_type::assign(__p[__sz], value_type()); + __init(__s, __sz, __sz); } template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) { @@ -1907,7 +1998,7 @@ } template -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()) { @@ -1919,7 +2010,7 @@ } template -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) { @@ -1931,6 +2022,7 @@ } template +_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())) { @@ -1946,6 +2038,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( const basic_string& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) @@ -1961,10 +2054,13 @@ } template +_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 (__sz < __min_cap) { + if (__sz < __min_cap && !__libcpp_is_constant_evaluated()) { __p = __get_short_pointer(); __set_short_size(__sz); } else { @@ -1972,6 +2068,7 @@ this->__throw_length_error(); size_t __cap = __recommend(__sz); __p = __alloc_traits::allocate(__alloc(), __cap + 1); + __begin_lifetime(__p, __cap + 1); __set_long_pointer(__p); __set_long_cap(__cap + 1); __set_long_size(__sz); @@ -1982,7 +2079,7 @@ #ifndef _LIBCPP_CXX03_LANG template -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::value) @@ -2000,7 +2097,7 @@ } template -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) { @@ -2008,7 +2105,13 @@ __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); else { - __r_.first().__r = __str.__r_.first().__r; + if (__libcpp_is_constant_evaluated()) + { + __r_.first() = __rep(); + __r_.first().__l = __str.__r_.first().__l; + } + else + __r_.first().__r = __str.__r_.first().__r; __str.__zero(); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -2021,13 +2124,16 @@ #endif // _LIBCPP_CXX03_LANG template +_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()) this->__throw_length_error(); pointer __p; - if (__n < __min_cap) + if (__n < __min_cap && !__libcpp_is_constant_evaluated()) { __set_short_size(__n); __p = __get_short_pointer(); @@ -2036,6 +2142,7 @@ { size_type __cap = __recommend(__n); __p = __alloc_traits::allocate(__alloc(), __cap+1); + __begin_lifetime(__p, __cap + 1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__n); @@ -2045,7 +2152,7 @@ } template -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()) { @@ -2056,7 +2163,7 @@ } template -template +template _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__default_init_tag(), __a) { @@ -2067,6 +2174,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a) @@ -2082,7 +2190,7 @@ } template -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) @@ -2098,6 +2206,7 @@ template template +_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) @@ -2112,6 +2221,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) : __r_(__default_init_tag(), __default_init_tag()) { @@ -2124,6 +2234,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) : __r_(__default_init_tag(), __a) { @@ -2136,6 +2247,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value @@ -2162,6 +2274,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value @@ -2172,7 +2285,7 @@ if (__sz > max_size()) this->__throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__sz < __min_cap && !__libcpp_is_constant_evaluated()) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -2181,6 +2294,7 @@ { size_type __cap = __recommend(__sz); __p = __alloc_traits::allocate(__alloc(), __cap+1); + __begin_lifetime(__p, __cap + 1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__sz); @@ -2206,7 +2320,7 @@ template template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) : __r_(__default_init_tag(), __default_init_tag()) { @@ -2218,7 +2332,7 @@ template template -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) @@ -2232,7 +2346,7 @@ #ifndef _LIBCPP_CXX03_LANG template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il) : __r_(__default_init_tag(), __default_init_tag()) @@ -2244,8 +2358,7 @@ } template -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) @@ -2259,16 +2372,23 @@ #endif // _LIBCPP_CXX03_LANG template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::~basic_string() { #if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->__erase_c(this); #endif - if (__is_long()) + if (__libcpp_is_constant_evaluated()) + { + if (__get_long_pointer() != nullptr) + __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); + } + else if (__is_long()) __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); } template +_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, @@ -2281,7 +2401,8 @@ size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; - pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); + pointer __p = __alloc_traits::allocate(__alloc(), __cap + 1); + __begin_lifetime(__p, __cap + 1); __invalidate_all_iterators(); if (__n_copy != 0) traits_type::copy(_VSTD::__to_address(__p), @@ -2302,6 +2423,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void 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) @@ -2314,6 +2436,7 @@ __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); + __begin_lifetime(__p, __cap + 1); __invalidate_all_iterators(); if (__n_copy != 0) traits_type::copy(_VSTD::__to_address(__p), @@ -2333,6 +2456,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( const value_type* __s, size_type __n) { @@ -2351,6 +2475,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_external( const value_type* __s, size_type __n) { @@ -2369,16 +2494,18 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); - return (__builtin_constant_p(__n) && __n < __min_cap) + return (__builtin_constant_p(__n) && __n < __min_cap && !__libcpp_is_constant_evaluated()) ? __assign_short(__s, __n) : __assign_external(__s, __n); } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { @@ -2397,6 +2524,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { @@ -2418,6 +2546,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { @@ -2439,7 +2568,7 @@ #ifndef _LIBCPP_CXX03_LANG template -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) @@ -2451,7 +2580,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 @@ -2472,12 +2601,17 @@ } __move_assign_alloc(__str); __r_.first() = __str.__r_.first(); + if (__libcpp_is_constant_evaluated()) + __str.__zero(); + else + { __str.__set_short_size(0); traits_type::assign(__str.__get_short_pointer()[0], value_type()); + } } template -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)) @@ -2491,6 +2625,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2505,6 +2640,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2540,6 +2676,7 @@ } template +_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) { @@ -2557,6 +2694,7 @@ && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, basic_string<_CharT, _Traits, _Allocator>& > +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) { __self_view __sv = __t; @@ -2574,6 +2712,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { @@ -2587,6 +2726,7 @@ // append template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { @@ -2610,6 +2750,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { @@ -2646,6 +2787,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { @@ -2684,6 +2826,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2718,7 +2861,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) { @@ -2726,6 +2869,7 @@ } template +_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) { @@ -2737,6 +2881,7 @@ template template +_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, @@ -2752,6 +2897,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2762,6 +2908,7 @@ // insert template +_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) { @@ -2794,6 +2941,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { @@ -2826,6 +2974,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2844,6 +2993,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2894,7 +3044,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) { @@ -2902,6 +3052,7 @@ } template +_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) @@ -2914,6 +3065,7 @@ template template +_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, @@ -2930,6 +3082,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { @@ -2938,6 +3091,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { @@ -2964,7 +3118,7 @@ } template -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) { @@ -2980,7 +3134,19 @@ // replace +template +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +basic_string<_CharT, _Traits, _Allocator>::__finish_replace(size_type& __sz, size_type& __n1, size_type& __n2, value_type*& __p) +{ + __sz += __n2 - __n1; + __set_size(__sz); + __invalidate_iterators_past(__sz); + traits_type::assign(__p[__sz], value_type()); +} + template +_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 @@ -3003,7 +3169,8 @@ { traits_type::move(__p + __pos, __s, __n2); traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); - goto __finish; + __finish_replace(__sz, __n1, __n2, __p); + return *this; } if (__p + __pos < __s && __s < __p + __sz) { @@ -3022,13 +3189,9 @@ } } traits_type::move(__p + __pos, __s, __n2); -__finish: // __sz += __n2 - __n1; in this and the below function below can cause unsigned // integer overflow, but this is a safe operation, so we disable the check. - __sz += __n2 - __n1; - __set_size(__sz); - __invalidate_iterators_past(__sz); - traits_type::assign(__p[__sz], value_type()); + __finish_replace(__sz, __n1, __n2, __p); } else __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); @@ -3036,6 +3199,7 @@ } template +_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) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK @@ -3071,6 +3235,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -3084,7 +3249,7 @@ } template -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) { @@ -3092,6 +3257,7 @@ } template +_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) @@ -3104,6 +3270,7 @@ template template +_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, @@ -3120,6 +3287,7 @@ } template +_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) { @@ -3128,7 +3296,7 @@ } template -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) { @@ -3137,7 +3305,7 @@ } template -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) { @@ -3145,7 +3313,7 @@ } template -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) { @@ -3153,7 +3321,7 @@ } template -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) { @@ -3185,6 +3353,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { @@ -3198,7 +3367,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { @@ -3216,7 +3385,7 @@ } template -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) { @@ -3233,7 +3402,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { @@ -3255,7 +3424,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { @@ -3273,7 +3442,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { @@ -3291,6 +3460,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { @@ -3313,7 +3483,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT { @@ -3326,6 +3496,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { @@ -3345,6 +3516,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { @@ -3355,6 +3527,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { @@ -3363,7 +3536,7 @@ pointer __new_data, __p; bool __was_long, __now_long; - if (__target_capacity == __min_cap - 1) + if (__target_capacity == __min_cap - 1 && !__libcpp_is_constant_evaluated()) { __was_long = true; __now_long = false; @@ -3373,7 +3546,10 @@ else { if (__target_capacity > __cap) + { __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + __begin_lifetime(__new_data, __target_capacity + 1); + } else { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -3381,6 +3557,7 @@ { #endif // _LIBCPP_NO_EXCEPTIONS __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + __begin_lifetime(__new_data, __target_capacity + 1); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3412,7 +3589,7 @@ } template -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 { @@ -3421,7 +3598,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { @@ -3430,6 +3607,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { @@ -3439,6 +3617,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { @@ -3448,7 +3627,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT { @@ -3457,7 +3636,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT { @@ -3466,7 +3645,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT { @@ -3475,7 +3654,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT { @@ -3484,6 +3663,7 @@ } template +_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 { @@ -3496,7 +3676,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const { @@ -3504,7 +3684,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 @@ -3541,6 +3721,7 @@ }; template +_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, @@ -3552,7 +3733,7 @@ } template -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 @@ -3563,6 +3744,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3577,7 +3759,7 @@ } template -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 @@ -3588,6 +3770,7 @@ } template +_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 @@ -3599,6 +3782,7 @@ // rfind template +_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, @@ -3610,7 +3794,7 @@ } template -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 @@ -3621,6 +3805,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3635,7 +3820,7 @@ } template -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 @@ -3646,6 +3831,7 @@ } template +_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 @@ -3657,6 +3843,7 @@ // find_first_of template +_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, @@ -3668,7 +3855,7 @@ } template -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 @@ -3679,6 +3866,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3693,7 +3881,7 @@ } template -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 @@ -3704,7 +3892,7 @@ } template -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 @@ -3715,6 +3903,7 @@ // find_last_of template +_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, @@ -3726,7 +3915,7 @@ } template -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 @@ -3737,6 +3926,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3751,7 +3941,7 @@ } template -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 @@ -3762,7 +3952,7 @@ } template -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 @@ -3773,6 +3963,7 @@ // find_first_not_of template +_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, @@ -3784,7 +3975,7 @@ } template -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 @@ -3795,6 +3986,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3809,7 +4001,7 @@ } template -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 @@ -3820,7 +4012,7 @@ } template -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 @@ -3832,6 +4024,7 @@ // find_last_not_of template +_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, @@ -3843,7 +4036,7 @@ } template -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 @@ -3854,6 +4047,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3868,7 +4062,7 @@ } template -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 @@ -3879,7 +4073,7 @@ } template -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 @@ -3892,6 +4086,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3914,7 +4109,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { @@ -3922,6 +4117,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3946,6 +4142,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3960,7 +4157,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3971,6 +4168,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -3988,6 +4186,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3999,6 +4198,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { @@ -4007,6 +4207,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -4019,13 +4220,13 @@ // __invariants template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { if (size() > capacity()) return false; - if (capacity() < __min_cap - 1) + if (capacity() < __min_cap - 1 && !__libcpp_is_constant_evaluated()) return false; if (data() == nullptr) return false; @@ -4037,7 +4238,7 @@ // __clear_and_shrink template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { @@ -4045,16 +4246,21 @@ if(__is_long()) { __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); - __set_long_cap(0); - __set_short_size(0); - traits_type::assign(*__get_short_pointer(), value_type()); + if (__libcpp_is_constant_evaluated()) + __zero(); + else + { + __set_long_cap(0); + __set_short_size(0); + traits_type::assign(*__get_short_pointer(), value_type()); + } } } // operator== template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4066,7 +4272,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const basic_string, _Allocator>& __lhs, const basic_string, _Allocator>& __rhs) _NOEXCEPT @@ -4085,7 +4291,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4098,7 +4304,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4111,7 +4317,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4120,7 +4326,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4129,7 +4335,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4140,7 +4346,7 @@ // operator< template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4149,7 +4355,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4158,7 +4364,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator< (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4169,7 +4375,7 @@ // operator> template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4178,7 +4384,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4187,7 +4393,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator> (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4198,7 +4404,7 @@ // operator<= template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4207,7 +4413,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4216,7 +4422,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4227,7 +4433,7 @@ // operator>= template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4236,7 +4442,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4245,7 +4451,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4256,6 +4462,7 @@ // operator + template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) @@ -4269,6 +4476,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4281,6 +4489,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4292,7 +4501,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { @@ -4305,6 +4514,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { @@ -4318,7 +4528,7 @@ #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { @@ -4326,7 +4536,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { @@ -4334,7 +4544,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { @@ -4342,7 +4552,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) { @@ -4350,7 +4560,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) { @@ -4359,7 +4569,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { @@ -4367,7 +4577,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { @@ -4380,7 +4590,7 @@ // swap template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) @@ -4543,33 +4753,33 @@ { inline namespace string_literals { - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator "" s( const char *__str, size_t __len ) { return basic_string (__str, __len); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator "" s( const wchar_t *__str, size_t __len ) { return basic_string (__str, __len); } #ifndef _LIBCPP_HAS_NO_CHAR8_T - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT { return basic_string (__str, __len); } #endif - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator "" s( const char16_t *__str, size_t __len ) { return basic_string (__str, __len); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator "" s( const char32_t *__str, size_t __len ) { return basic_string (__str, __len); diff --git a/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp b/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp --- a/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp +++ b/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp @@ -23,16 +23,24 @@ template struct test_traits { - typedef charT char_type; + typedef charT char_type; + typedef int int_type; + static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT { + __c1 = __c2; + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { + return std::__libcpp_is_constant_evaluated() ? _VSTD::__assign_constexpr(__s, __n, __a) + : __n == 0 ? __s + : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n); + } + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type((unsigned char)__c); } }; -void round_trip ( const char *p ) { - std::stringstream ss; - ss << std::quoted(p); - std::basic_string> s; - ss >> std::quoted(s); // expected-error {{invalid operands to binary expression}} +void round_trip(const char* p) { + std::stringstream ss; + ss << std::quoted(p); + std::basic_string > s; + ss >> std::quoted(s); // expected-error {{invalid operands to binary expression}} } -int main(int, char**) { - round_trip("Hi Mom"); -} +int main(int, char**) { round_trip("Hi Mom"); } diff --git a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp @@ -20,59 +20,72 @@ #include "test_macros.h" template -void -test(S s, typename S::size_type pos) -{ - const S& cs = s; - if (pos < s.size()) - { - assert(s.at(pos) == s[pos]); - assert(cs.at(pos) == cs[pos]); - } +TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos) { + const S& cs = s; + if (pos < s.size()) { + assert(s.at(pos) == s[pos]); + assert(cs.at(pos) == cs[pos]); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { - try - { - TEST_IGNORE_NODISCARD s.at(pos); - assert(false); - } - catch (std::out_of_range&) - { - assert(pos >= s.size()); - } - try - { - TEST_IGNORE_NODISCARD cs.at(pos); - assert(false); - } - catch (std::out_of_range&) - { - assert(pos >= s.size()); - } + else { + try { + TEST_IGNORE_NODISCARD s.at(pos); + assert(false); + } catch (std::out_of_range&) { + assert(pos >= s.size()); + } + try { + TEST_IGNORE_NODISCARD cs.at(pos); + assert(false); + } catch (std::out_of_range&) { + assert(pos >= s.size()); } + } #endif } -int main(int, char**) -{ - { +bool test() { + { typedef std::string S; test(S(), 0); + test(S("123"), 3); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator > S; + test(S(), 0); + test(S("123"), 3); + } +#endif + return true; +} + +TEST_CONSTEXPR_CXX20 +bool constexpr_test() { + { + typedef std::string S; test(S("123"), 0); test(S("123"), 1); test(S("123"), 2); - test(S("123"), 3); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; - test(S(), 0); + { + typedef std::basic_string, min_allocator > S; test(S("123"), 0); test(S("123"), 1); test(S("123"), 2); - test(S("123"), 3); - } + } +#endif + return true; +} + +int main(int, char**) { + + test(); + constexpr_test(); + +#if TEST_STD_VER > 17 + static_assert(constexpr_test()); #endif return 0; diff --git a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp @@ -18,34 +18,42 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - ASSERT_SAME_TYPE(decltype( s.back()), typename S::reference); - ASSERT_SAME_TYPE(decltype(cs.back()), typename S::const_reference); - LIBCPP_ASSERT_NOEXCEPT( s.back()); - LIBCPP_ASSERT_NOEXCEPT( cs.back()); - assert(&cs.back() == &cs[cs.size()-1]); - assert(&s.back() == &s[cs.size()-1]); - s.back() = typename S::value_type('z'); - assert(s.back() == typename S::value_type('z')); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + ASSERT_SAME_TYPE(decltype(s.back()), typename S::reference); + ASSERT_SAME_TYPE(decltype(cs.back()), typename S::const_reference); + LIBCPP_ASSERT_NOEXCEPT(s.back()); + LIBCPP_ASSERT_NOEXCEPT(cs.back()); + assert(&cs.back() == &cs[cs.size() - 1]); + assert(&s.back() == &s[cs.size() - 1]); + s.back() = typename S::value_type('z'); + assert(s.back() == typename S::value_type('z')); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S("1")); test(S("1234567890123456789012345678901234567890")); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; + { + typedef std::basic_string, min_allocator > S; test(S("1")); test(S("1234567890123456789012345678901234567890")); - } + } +#endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); #endif - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp @@ -18,34 +18,42 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - ASSERT_SAME_TYPE(decltype( s.front()), typename S::reference); - ASSERT_SAME_TYPE(decltype(cs.front()), typename S::const_reference); - LIBCPP_ASSERT_NOEXCEPT( s.front()); - LIBCPP_ASSERT_NOEXCEPT( cs.front()); - assert(&cs.front() == &cs[0]); - assert(&s.front() == &s[0]); - s.front() = typename S::value_type('z'); - assert(s.front() == typename S::value_type('z')); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + ASSERT_SAME_TYPE(decltype(s.front()), typename S::reference); + ASSERT_SAME_TYPE(decltype(cs.front()), typename S::const_reference); + LIBCPP_ASSERT_NOEXCEPT(s.front()); + LIBCPP_ASSERT_NOEXCEPT(cs.front()); + assert(&cs.front() == &cs[0]); + assert(&s.front() == &s[0]); + s.front() = typename S::value_type('z'); + assert(s.front() == typename S::value_type('z')); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S("1")); test(S("1234567890123456789012345678901234567890")); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; + { + typedef std::basic_string, min_allocator > S; test(S("1")); test(S("1234567890123456789012345678901234567890")); - } + } +#endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); #endif - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp @@ -17,44 +17,52 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; S s("0123456789"); const S& cs = s; - ASSERT_SAME_TYPE(decltype( s[0]), typename S::reference); + ASSERT_SAME_TYPE(decltype(s[0]), typename S::reference); ASSERT_SAME_TYPE(decltype(cs[0]), typename S::const_reference); - LIBCPP_ASSERT_NOEXCEPT( s[0]); - LIBCPP_ASSERT_NOEXCEPT( cs[0]); - for (S::size_type i = 0; i < cs.size(); ++i) - { - assert(s[i] == static_cast('0' + i)); - assert(cs[i] == s[i]); + LIBCPP_ASSERT_NOEXCEPT(s[0]); + LIBCPP_ASSERT_NOEXCEPT(cs[0]); + for (S::size_type i = 0; i < cs.size(); ++i) { + assert(s[i] == static_cast('0' + i)); + assert(cs[i] == s[i]); } assert(cs[cs.size()] == '\0'); const S s2 = S(); assert(s2[0] == '\0'); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; + { + typedef std::basic_string, min_allocator > S; S s("0123456789"); const S& cs = s; - ASSERT_SAME_TYPE(decltype( s[0]), typename S::reference); + ASSERT_SAME_TYPE(decltype(s[0]), typename S::reference); ASSERT_SAME_TYPE(decltype(cs[0]), typename S::const_reference); - LIBCPP_ASSERT_NOEXCEPT( s[0]); - LIBCPP_ASSERT_NOEXCEPT( cs[0]); - for (S::size_type i = 0; i < cs.size(); ++i) - { - assert(s[i] == static_cast('0' + i)); - assert(cs[i] == s[i]); + LIBCPP_ASSERT_NOEXCEPT(s[0]); + LIBCPP_ASSERT_NOEXCEPT(cs[0]); + for (S::size_type i = 0; i < cs.size(); ++i) { + assert(s[i] == static_cast('0' + i)); + assert(cs[i] == s[i]); } assert(cs[cs.size()] == '\0'); const S s2 = S(); assert(s2[0] == '\0'); - } + } +#endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); #endif - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp @@ -19,30 +19,29 @@ #include "test_macros.h" template -void -test(S s) -{ +TEST_CONSTEXPR_CXX20 void test(S s) { + if (!TEST_IS_CONSTANT_EVALUATED) S::allocator_type::throw_after = 0; #ifndef TEST_HAS_NO_EXCEPTIONS - try + try #endif - { - while (s.size() < s.capacity()) - s.push_back(typename S::value_type()); - assert(s.size() == s.capacity()); - } + { + while (s.size() < s.capacity()) + s.push_back(typename S::value_type()); + assert(s.size() == s.capacity()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - catch (...) - { - assert(false); - } + catch (...) { + assert(false); + } #endif + if (!TEST_IS_CONSTANT_EVALUATED) S::allocator_type::throw_after = INT_MAX; } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::basic_string, test_allocator > S; S s; test(s); @@ -52,13 +51,24 @@ s.assign(100, 'a'); s.erase(50); test(s); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; + { + typedef std::basic_string, min_allocator > S; S s; assert(s.capacity() > 0); - } + } +#endif + + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); #endif return 0; diff --git a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp @@ -17,16 +17,14 @@ #include "min_allocator.h" template -void -test(S s) -{ - s.clear(); - assert(s.size() == 0); +TEST_CONSTEXPR_CXX20 void test(S s) { + s.clear(); + assert(s.size() == 0); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; S s; test(s); @@ -55,5 +53,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp @@ -17,28 +17,36 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - ASSERT_NOEXCEPT(s.empty()); - assert(s.empty() == (s.size() == 0)); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + ASSERT_NOEXCEPT(s.empty()); + assert(s.empty() == (s.size() == 0)); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); - } + } #if TEST_STD_VER >= 11 - { - typedef std::basic_string, min_allocator> S; + { + typedef std::basic_string, min_allocator > S; test(S()); test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); - } + } +#endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); #endif return 0; diff --git a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp @@ -17,15 +17,13 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - assert(s.length() == s.size()); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + assert(s.length() == s.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -40,5 +38,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp @@ -23,82 +23,78 @@ #include "min_allocator.h" template -void -test(typename S::size_type min_cap, typename S::size_type erased_index, typename S::size_type res_arg) -{ - S s(min_cap, 'a'); - s.erase(erased_index); - assert(s.size() == erased_index); - assert(s.capacity() >= min_cap); // Check that we really have at least this capacity. +void test(typename S::size_type min_cap, typename S::size_type erased_index, typename S::size_type res_arg) { + S s(min_cap, 'a'); + s.erase(erased_index); + assert(s.size() == erased_index); + assert(s.capacity() >= min_cap); // Check that we really have at least this capacity. #if TEST_STD_VER > 17 - typename S::size_type old_cap = s.capacity(); + typename S::size_type old_cap = s.capacity(); #endif - S s0 = s; - if (res_arg <= s.max_size()) - { - s.reserve(res_arg); - LIBCPP_ASSERT(s.__invariants()); - assert(s == s0); - assert(s.capacity() >= res_arg); - assert(s.capacity() >= s.size()); + S s0 = s; + if (res_arg <= s.max_size()) { + s.reserve(res_arg); + LIBCPP_ASSERT(s.__invariants()); + assert(s == s0); + assert(s.capacity() >= res_arg); + assert(s.capacity() >= s.size()); #if TEST_STD_VER > 17 - assert(s.capacity() >= old_cap); // reserve never shrinks as of P0966 (C++20) + assert(s.capacity() >= old_cap); // reserve never shrinks as of P0966 (C++20) #endif - } + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { - try - { - s.reserve(res_arg); - LIBCPP_ASSERT(s.__invariants()); - assert(false); - } - catch (std::length_error&) - { - assert(res_arg > s.max_size()); - } + else { + try { + s.reserve(res_arg); + LIBCPP_ASSERT(s.__invariants()); + assert(false); + } catch (std::length_error&) { + assert(res_arg > s.max_size()); } + } #endif } -int main(int, char**) -{ - { +void test() { + { typedef std::string S; { - test(0, 0, 5); - test(0, 0, 10); - test(0, 0, 50); + test(0, 0, 5); + test(0, 0, 10); + test(0, 0, 50); } { - test(100, 50, 5); - test(100, 50, 10); - test(100, 50, 50); - test(100, 50, 100); - test(100, 50, 1000); - test(100, 50, S::npos); - } + test(100, 50, 5); + test(100, 50, 10); + test(100, 50, 50); + test(100, 50, 100); + test(100, 50, 1000); + test(100, 50, S::npos); } + } #if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator > S; { - typedef std::basic_string, min_allocator> S; - { - test(0, 0, 5); - test(0, 0, 10); - test(0, 0, 50); + test(0, 0, 5); + test(0, 0, 10); + test(0, 0, 50); } { - test(100, 50, 5); - test(100, 50, 10); - test(100, 50, 50); - test(100, 50, 100); - test(100, 50, 1000); - test(100, 50, S::npos); - } + test(100, 50, 5); + test(100, 50, 10); + test(100, 50, 50); + test(100, 50, 100); + test(100, 50, 1000); + test(100, 50, S::npos); } + } #endif +} + +int main(int, char**) { + test(); return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp @@ -18,18 +18,14 @@ #include "min_allocator.h" template -void -test(S s, typename S::size_type n, S expected) -{ - if (n <= s.max_size()) - { - s.resize(n); - LIBCPP_ASSERT(s.__invariants()); - assert(s == expected); - } +TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type n, S expected) { + if (n <= s.max_size()) { + s.resize(n); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { + else { try { s.resize(n); @@ -43,9 +39,24 @@ #endif } -int main(int, char**) -{ - { +bool test() { + { + typedef std::string S; + test(S(), S::npos, S("not going to happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator > S; + test(S(), S::npos, S("not going to happen")); + } +#endif + + return true; +} + +TEST_CONSTEXPR_CXX20 +bool constexpr_test() { + { typedef std::string S; test(S(), 0, S()); test(S(), 1, S(1, '\0')); @@ -62,7 +73,6 @@ S("12345678901234567890123456789012345678901234567890")); test(S("12345678901234567890123456789012345678901234567890"), 60, S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60)); - test(S(), S::npos, S("not going to happen")); } #if TEST_STD_VER >= 11 { @@ -82,9 +92,20 @@ S("12345678901234567890123456789012345678901234567890")); test(S("12345678901234567890123456789012345678901234567890"), 60, S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60)); - test(S(), S::npos, S("not going to happen")); } #endif + return true; +} + +int main(int, char**) { + + test(); + constexpr_test(); + +#if TEST_STD_VER > 17 + static_assert(constexpr_test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp @@ -18,18 +18,14 @@ #include "min_allocator.h" template -void -test(S s, typename S::size_type n, typename S::value_type c, S expected) -{ - if (n <= s.max_size()) - { - s.resize(n, c); - LIBCPP_ASSERT(s.__invariants()); - assert(s == expected); - } +TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type n, typename S::value_type c, S expected) { + if (n <= s.max_size()) { + s.resize(n, c); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { + else { try { s.resize(n, c); @@ -43,9 +39,24 @@ #endif } -int main(int, char**) -{ - { +bool test() { + { + typedef std::string S; + test(S(), S::npos, 'a', S("not going to happen")); + } +#if TEST_STD_VER >= 11 + { + typedef std::basic_string, min_allocator > S; + test(S(), S::npos, 'a', S("not going to happen")); + } +#endif + + return true; +} + +TEST_CONSTEXPR_CXX20 +bool constexpr_test() { + { typedef std::string S; test(S(), 0, 'a', S()); test(S(), 1, 'a', S("a")); @@ -62,7 +73,6 @@ S("12345678901234567890123456789012345678901234567890")); test(S("12345678901234567890123456789012345678901234567890"), 60, 'a', S("12345678901234567890123456789012345678901234567890aaaaaaaaaa")); - test(S(), S::npos, 'a', S("not going to happen")); } #if TEST_STD_VER >= 11 { @@ -82,9 +92,20 @@ S("12345678901234567890123456789012345678901234567890")); test(S("12345678901234567890123456789012345678901234567890"), 60, 'a', S("12345678901234567890123456789012345678901234567890aaaaaaaaaa")); - test(S(), S::npos, 'a', S("not going to happen")); } #endif + return true; +} + +int main(int, char**) { + + test(); + constexpr_test(); + +#if TEST_STD_VER > 17 + static_assert(constexpr_test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp @@ -17,21 +17,19 @@ #include "min_allocator.h" template -void -test(S s) -{ - typename S::size_type old_cap = s.capacity(); - S s0 = s; - s.shrink_to_fit(); - LIBCPP_ASSERT(s.__invariants()); - assert(s == s0); - assert(s.capacity() <= old_cap); - assert(s.capacity() >= s.size()); +TEST_CONSTEXPR_CXX20 void test(S s) { + typename S::size_type old_cap = s.capacity(); + S s0 = s; + s.shrink_to_fit(); + LIBCPP_ASSERT(s.__invariants()); + assert(s == s0); + assert(s.capacity() <= old_cap); + assert(s.capacity() >= s.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; S s; test(s); @@ -60,5 +58,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp @@ -17,15 +17,13 @@ #include "min_allocator.h" template -void -test(const S& s, typename S::size_type c) -{ - assert(s.size() == c); +TEST_CONSTEXPR_CXX20 void test(const S& s, typename S::size_type c) { + assert(s.size() == c); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S(), 0); test(S("123"), 3); @@ -40,5 +38,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp @@ -18,10 +18,8 @@ #include "min_allocator.h" template -void -test() -{ - { +TEST_CONSTEXPR_CXX20 void test() { + { #if TEST_STD_VER > 14 static_assert((noexcept(S{})), "" ); #elif TEST_STD_VER >= 11 @@ -52,11 +50,9 @@ #if TEST_STD_VER >= 11 template -void -test2() -{ - { -#if TEST_STD_VER > 14 +TEST_CONSTEXPR_CXX20 void test2() { + { +# if TEST_STD_VER > 14 static_assert((noexcept(S{})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" ); @@ -85,13 +81,24 @@ #endif -int main(int, char**) -{ - test, test_allocator > >(); +TEST_CONSTEXPR_CXX20 +bool test() { + test, test_allocator > >(); #if TEST_STD_VER >= 11 test2, min_allocator > >(); test2, explicit_allocator > >(); #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp @@ -18,8 +18,8 @@ #include "test_macros.h" -int main(int, char**) -{ +TEST_CONSTEXPR_CXX20 +bool test() { // Test that assignment from {} and {ptr, len} are allowed and are not // ambiguous. { @@ -33,5 +33,16 @@ assert(s == "ab"); } + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp @@ -17,20 +17,18 @@ #include "min_allocator.h" template -void -test(S s1, typename S::value_type s2) -{ - typedef typename S::traits_type T; - s1 = s2; - LIBCPP_ASSERT(s1.__invariants()); - assert(s1.size() == 1); - assert(T::eq(s1[0], s2)); - assert(s1.capacity() >= s1.size()); +TEST_CONSTEXPR_CXX20 void test(S s1, typename S::value_type s2) { + typedef typename S::traits_type T; + s1 = s2; + LIBCPP_ASSERT(s1.__invariants()); + assert(s1.size() == 1); + assert(T::eq(s1[0], s2)); + assert(s1.capacity() >= s1.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S(), 'a'); test(S("1"), 'a'); @@ -47,5 +45,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp @@ -18,19 +18,17 @@ #include "min_allocator.h" template -void -test(S s1) -{ - S s2 = s1; - LIBCPP_ASSERT(s2.__invariants()); - assert(s2 == s1); - assert(s2.capacity() >= s2.size()); - assert(s2.get_allocator() == s1.get_allocator()); +TEST_CONSTEXPR_CXX20 void test(S s1) { + S s2 = s1; + LIBCPP_ASSERT(s2.__invariants()); + assert(s2 == s1); + assert(s2.capacity() >= s2.size()); + assert(s2.get_allocator() == s1.get_allocator()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; typedef std::basic_string, A> S; test(S(A(3))); @@ -47,5 +45,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp @@ -21,20 +21,29 @@ struct alloc_imp { bool active; + TEST_CONSTEXPR_CXX20 alloc_imp() : active(true) {} template - T* allocate(std::size_t n) - { - if (active) - return static_cast(std::malloc(n * sizeof(T))); - else - throw std::bad_alloc(); + TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { + if (active) { + if (TEST_IS_CONSTANT_EVALUATED) + return std::allocator().allocate(n); + return static_cast(std::malloc(n * sizeof(T))); + } else + throw std::bad_alloc(); } template - void deallocate(T* p, std::size_t) { std::free(p); } + TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t s) { + if (TEST_IS_CONSTANT_EVALUATED) + std::allocator().deallocate(p, s); + else + std::free(p); + } + TEST_CONSTEXPR_CXX20 void activate () { active = true; } + TEST_CONSTEXPR_CXX20 void deactivate() { active = false; } }; @@ -45,69 +54,51 @@ alloc_imp *imp; + TEST_CONSTEXPR_CXX20 poca_alloc(alloc_imp *imp_) : imp (imp_) {} template poca_alloc(const poca_alloc& other) : imp(other.imp) {} + TEST_CONSTEXPR_CXX20 T* allocate (std::size_t n) { return imp->allocate(n);} + TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } }; template -bool operator==(const poca_alloc& lhs, const poca_alloc& rhs) -{ - return lhs.imp == rhs.imp; +TEST_CONSTEXPR_CXX20 bool operator==(const poca_alloc& lhs, const poca_alloc& rhs) { + return lhs.imp == rhs.imp; } template -bool operator!=(const poca_alloc& lhs, const poca_alloc& rhs) -{ - return lhs.imp != rhs.imp; +TEST_CONSTEXPR_CXX20 bool operator!=(const poca_alloc& lhs, const poca_alloc& rhs) { + return lhs.imp != rhs.imp; } template -void test_assign(S &s1, const S& s2) -{ - try { s1 = s2; } - catch ( std::bad_alloc &) { return; } - assert(false); +TEST_CONSTEXPR_CXX20 void test_assign(S& s1, const S& s2) { + try { + s1 = s2; + } catch (std::bad_alloc&) { + return; + } + assert(false); } #endif - - template -void -test(S s1, const typename S::allocator_type& a) -{ - S s2(s1, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2 == s1); - assert(s2.capacity() >= s2.size()); - assert(s2.get_allocator() == a); +TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::allocator_type& a) { + S s2(s1, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2 == s1); + assert(s2.capacity() >= s2.size()); + assert(s2.get_allocator() == a); } -int main(int, char**) -{ - { - typedef test_allocator A; - typedef std::basic_string, A> S; - test(S(), A(3)); - test(S("1"), A(5)); - test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); - } -#if TEST_STD_VER >= 11 - { - typedef min_allocator A; - typedef std::basic_string, A> S; - test(S(), A()); - test(S("1"), A()); - test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); - } - -#ifndef TEST_HAS_NO_EXCEPTIONS - { +bool test() { +#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) + { typedef poca_alloc A; typedef std::basic_string, A> S; const char * p1 = "This is my first string"; @@ -127,6 +118,40 @@ assert(s2 == p2); } #endif + + return true; +} + +TEST_CONSTEXPR_CXX20 +bool constexpr_test() { + { + typedef test_allocator A; + typedef std::basic_string, A> S; + test(S(), A(3)); + test(S("1"), A(5)); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); + } +#if TEST_STD_VER >= 11 + { + typedef min_allocator A; + typedef std::basic_string, A> S; + test(S(), A()); + test(S("1"), A()); + test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); + } + +#endif + + return true; +} + +int main(int, char**) { + + test(); + constexpr_test(); + +#if TEST_STD_VER > 17 + static_assert(constexpr_test()); #endif return 0; diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp @@ -18,18 +18,16 @@ #include "min_allocator.h" template -void -test(S s1, const S& s2) -{ - s1 = s2; - LIBCPP_ASSERT(s1.__invariants()); - assert(s1 == s2); - assert(s1.capacity() >= s1.size()); +TEST_CONSTEXPR_CXX20 void test(S s1, const S& s2) { + s1 = s2; + LIBCPP_ASSERT(s1.__invariants()); + assert(s1 == s2); + assert(s1.capacity() >= s1.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S(), S()); test(S("1"), S()); @@ -46,7 +44,7 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890"), S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); - } + } #if TEST_STD_VER >= 11 { typedef std::basic_string, min_allocator> S; @@ -77,5 +75,16 @@ } #endif + return true; +} + +int main(int, char**) { + + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h --- a/libcxx/test/support/test_allocator.h +++ b/libcxx/test/support/test_allocator.h @@ -20,6 +20,12 @@ #include "test_macros.h" +#if TEST_STD_VER > 17 +#define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated() +#else +#define TEST_IS_CONSTANT_EVALUATED false +#endif + template inline typename std::allocator_traits::size_type alloc_max_size(Alloc const &a) { @@ -86,21 +92,34 @@ template struct rebind {typedef test_allocator other;}; - test_allocator() TEST_NOEXCEPT : data_(0), id_(0) {++count;} - explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) - {++count;} + TEST_CONSTEXPR_CXX20 + test_allocator() TEST_NOEXCEPT : data_(0), id_(0) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX20 + explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX20 test_allocator(const test_allocator& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) { - ++count; - ++copied; + if (!TEST_IS_CONSTANT_EVALUATED) { + ++count; + ++copied; + } assert(a.data_ != destructed_value && a.id_ != destructed_value && "copying from destroyed allocator"); } #if TEST_STD_VER >= 11 + TEST_CONSTEXPR_CXX20 test_allocator(test_allocator&& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) { - ++count; - ++moved; + if (!TEST_IS_CONSTANT_EVALUATED) { + ++count; + ++moved; + } assert(a.data_ != destructed_value && a.id_ != destructed_value && "moving from destroyed allocator"); a.data_ = moved_value; @@ -108,35 +127,52 @@ } #endif template + TEST_CONSTEXPR_CXX20 test_allocator(const test_allocator& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) { ++count; ++converted; } + TEST_CONSTEXPR_CXX20 ~test_allocator() TEST_NOEXCEPT { assert(data_ >= 0); assert(id_ >= 0); - --count; + if (!TEST_IS_CONSTANT_EVALUATED) { + --count; + } data_ = destructed_value; id_ = destructed_value; } pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} + TEST_CONSTEXPR_CXX20 pointer allocate(size_type n, const void* = 0) { assert(data_ >= 0); - if (time_to_throw >= throw_after) { + if (!TEST_IS_CONSTANT_EVALUATED && time_to_throw >= throw_after) { #ifndef TEST_HAS_NO_EXCEPTIONS throw std::bad_alloc(); #else std::terminate(); #endif } - ++time_to_throw; - ++alloc_count; - return (pointer)::operator new(n * sizeof(T)); + if (!TEST_IS_CONSTANT_EVALUATED) { + ++time_to_throw; + ++alloc_count; + return (pointer)::operator new(n * sizeof(T)); + } + return std::allocator().allocate(n); } - void deallocate(pointer p, size_type) - {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);} + TEST_CONSTEXPR_CXX20 + void deallocate(pointer p, size_type s) { + assert(data_ >= 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + --alloc_count; + ::operator delete((void*)p); + } + else + std::allocator().deallocate(p, s); + } + TEST_CONSTEXPR_CXX20 size_type max_size() const TEST_NOEXCEPT {return UINT_MAX / sizeof(T);} #if TEST_STD_VER < 11 @@ -148,8 +184,10 @@ #endif void destroy(pointer p) {p->~T();} + TEST_CONSTEXPR_CXX20 friend bool operator==(const test_allocator& x, const test_allocator& y) {return x.data_ == y.data_;} + TEST_CONSTEXPR_CXX20 friend bool operator!=(const test_allocator& x, const test_allocator& y) {return !(x == y);}