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_AFTER_CXX11 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_AFTER_CXX11 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_AFTER_CXX11 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_AFTER_CXX11 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 @@ -289,22 +289,21 @@ template static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT { - if (__n == 0) return __s1; - if (__s1 < __s2) { - _VSTD::copy(__s2, __s2 + __n, __s1); - } else if (__s2 < __s1) { - _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n); - } + _VSTD::copy_n(__s2, __n, __s1); return __s1; } template static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT { - _VSTD::copy_n(__s2, __n, __s1); + if (__n == 0) return __s1; + _CharT* __alloc = new _CharT[__n]; + __copy_constexpr(__alloc, __s2, __n); + __copy_constexpr(__s1, static_cast(__alloc), __n); + delete[] __alloc; return __s1; } 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_AFTER_CXX11 void __begin_lifetime(pointer __p, size_type __count) + { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) + { + for (size_type __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 @@ -2143,6 +2255,8 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { __zero(); + if (__libcpp_is_constant_evaluated()) + __init(size_type(), value_type()); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2162,17 +2276,20 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { + if (__libcpp_is_constant_evaluated()) + __zero(); size_type __sz = static_cast(_VSTD::distance(__first, __last)); 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 +2298,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 +2324,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 +2336,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 +2350,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 +2362,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 +2376,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 +2405,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 +2427,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 +2440,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 +2460,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 +2479,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 +2498,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 +2528,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { @@ -2418,6 +2550,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { @@ -2439,7 +2572,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 +2584,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 +2605,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 +2629,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2505,6 +2644,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2540,6 +2680,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 +2698,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,12 +2716,13 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); return __builtin_constant_p(*__s) - ? (traits_type::length(__s) < __min_cap + ? (traits_type::length(__s) < __min_cap && !__libcpp_is_constant_evaluated() ? __assign_short(__s, traits_type::length(__s)) : __assign_external(__s, traits_type::length(__s))) : __assign_external(__s); @@ -2587,6 +2730,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 +2754,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 +2791,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { @@ -2684,6 +2830,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2718,7 +2865,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 +2873,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 +2885,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 +2901,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2762,6 +2912,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 +2945,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 +2978,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2844,6 +2997,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2894,7 +3048,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 +3056,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 +3069,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 +3086,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 +3095,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 +3122,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 +3138,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 +3173,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 +3193,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 +3203,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 +3239,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -3084,7 +3253,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 +3261,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 +3274,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 +3291,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 +3300,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 +3309,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 +3317,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 +3325,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 +3357,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 +3371,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 +3389,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 +3406,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { @@ -3255,7 +3428,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { @@ -3273,7 +3446,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { @@ -3291,6 +3464,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { @@ -3313,7 +3487,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 +3500,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { @@ -3345,6 +3520,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { @@ -3355,6 +3531,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { @@ -3363,7 +3540,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 +3550,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 +3561,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 +3593,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 +3602,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 +3611,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 +3621,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { @@ -3448,7 +3631,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT { @@ -3457,7 +3640,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 +3649,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT { @@ -3475,7 +3658,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 +3667,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 +3680,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 +3688,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 +3725,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 +3737,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 +3748,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3577,7 +3763,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 +3774,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 +3786,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 +3798,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 +3809,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3635,7 +3824,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 +3835,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 +3847,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 +3859,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 +3870,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3693,7 +3885,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 +3896,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 +3907,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 +3919,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 +3930,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3751,7 +3945,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 +3956,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 +3967,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 +3979,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 +3990,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3809,7 +4005,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 +4016,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 +4028,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 +4040,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 +4051,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3868,7 +4066,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 +4077,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 +4090,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3914,7 +4113,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { @@ -3922,6 +4121,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3946,6 +4146,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3960,7 +4161,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3971,6 +4172,7 @@ template template +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -3988,6 +4190,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3999,6 +4202,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { @@ -4007,6 +4211,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -4019,13 +4224,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 +4242,7 @@ // __clear_and_shrink template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { @@ -4045,16 +4250,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 +4276,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 +4295,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 +4308,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 +4321,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 +4330,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 +4339,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 +4350,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 +4359,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 +4368,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 +4379,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 +4388,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 +4397,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 +4408,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 +4417,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 +4426,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 +4437,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 +4446,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 +4455,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 +4466,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 +4480,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4281,6 +4493,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4292,7 +4505,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 +4518,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { @@ -4318,7 +4532,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 +4540,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 +4548,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 +4556,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 +4564,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 +4573,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 +4581,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 +4594,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 +4757,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/cpp17_input_iterator.h b/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h --- a/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h +++ b/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h @@ -22,17 +22,25 @@ typedef It pointer; typedef typename std::iterator_traits::reference reference; + TEST_CONSTEXPR_CXX20 cpp17_input_iterator() : it_() {} + TEST_CONSTEXPR_CXX20 explicit cpp17_input_iterator(It it) : it_(it) {} + TEST_CONSTEXPR_CXX20 reference operator*() const {return *it_;} + TEST_CONSTEXPR_CXX20 pointer operator->() const {return it_;} + TEST_CONSTEXPR_CXX20 cpp17_input_iterator& operator++() {++it_; return *this;} + TEST_CONSTEXPR_CXX20 cpp17_input_iterator operator++(int) {cpp17_input_iterator tmp(*this); ++(*this); return tmp;} + TEST_CONSTEXPR_CXX20 friend bool operator==(const cpp17_input_iterator& x, const cpp17_input_iterator& y) {return x.it_ == y.it_;} + TEST_CONSTEXPR_CXX20 friend bool operator!=(const cpp17_input_iterator& x, const cpp17_input_iterator& y) {return !(x == y);} }; 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/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp @@ -25,26 +25,22 @@ #include "min_allocator.h" template -void -test(SV sv, std::size_t pos, std::size_t n) -{ - typedef typename S::traits_type T; - typedef typename S::allocator_type A; - typedef typename S::size_type Size; - if (pos <= sv.size()) - { - S s2(sv, static_cast(pos), static_cast(n)); - LIBCPP_ASSERT(s2.__invariants()); - assert(pos <= sv.size()); - std::size_t rlen = std::min(sv.size() - pos, n); - assert(s2.size() == rlen); - assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); - } +TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n) { + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + typedef typename S::size_type Size; + if (pos <= sv.size()) { + S s2(sv, static_cast(pos), static_cast(n)); + LIBCPP_ASSERT(s2.__invariants()); + assert(pos <= sv.size()); + std::size_t rlen = std::min(sv.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { + else if (!TEST_IS_CONSTANT_EVALUATED) { try { S s2(sv, static_cast(pos), static_cast(n)); @@ -54,30 +50,26 @@ { assert(pos > sv.size()); } - } + } #endif } template -void -test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a) -{ - typedef typename S::traits_type T; - typedef typename S::size_type Size; - if (pos <= sv.size()) - { - S s2(sv, static_cast(pos), static_cast(n), a); - LIBCPP_ASSERT(s2.__invariants()); - assert(pos <= sv.size()); - std::size_t rlen = std::min(sv.size() - pos, n); - assert(s2.size() == rlen); - assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); - } +TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a) { + typedef typename S::traits_type T; + typedef typename S::size_type Size; + if (pos <= sv.size()) { + S s2(sv, static_cast(pos), static_cast(n), a); + LIBCPP_ASSERT(s2.__invariants()); + assert(pos <= sv.size()); + std::size_t rlen = std::min(sv.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { + else if (!TEST_IS_CONSTANT_EVALUATED) { try { S s2(sv, static_cast(pos), static_cast(n), a); @@ -87,14 +79,13 @@ { assert(pos > sv.size()); } - } + } #endif } -int main(int, char**) -{ - - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; typedef std::basic_string_view > SV; typedef std::basic_string , A> S; @@ -184,5 +175,16 @@ assert(s7 == "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/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/std/strings/basic.string/string.cons/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp @@ -19,28 +19,39 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) -{ - { - std::string s = {'a', 'b', 'c'}; - assert(s == "abc"); - } - { - std::wstring s; - s = {L'a', L'b', L'c'}; - assert(s == L"abc"); - } - { - typedef std::basic_string, min_allocator> S; - S s = {'a', 'b', 'c'}; - assert(s == "abc"); - } - { - typedef std::basic_string, min_allocator> S; - S s; - s = {L'a', L'b', L'c'}; - assert(s == L"abc"); - } +TEST_CONSTEXPR_CXX20 +bool test() { + { + std::string s = {'a', 'b', 'c'}; + assert(s == "abc"); + } + { + std::wstring s; + s = {L'a', L'b', L'c'}; + assert(s == L"abc"); + } + { + typedef std::basic_string, min_allocator > S; + S s = {'a', 'b', 'c'}; + assert(s == "abc"); + } + { + typedef std::basic_string, min_allocator > S; + S s; + s = {L'a', L'b', L'c'}; + assert(s == L"abc"); + } + + 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/initializer_list_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp @@ -18,19 +18,30 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) -{ - { - std::string s; - s = {'a', 'b', 'c'}; - assert(s == "abc"); - } - { - typedef std::basic_string, min_allocator> S; - S s; - s = {'a', 'b', 'c'}; - assert(s == "abc"); - } +TEST_CONSTEXPR_CXX20 +bool test() { + { + std::string s; + s = {'a', 'b', 'c'}; + assert(s == "abc"); + } + { + typedef std::basic_string, min_allocator > S; + S s; + s = {'a', 'b', 'c'}; + assert(s == "abc"); + } + + 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/iter_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp @@ -24,41 +24,37 @@ #include "min_allocator.h" template -void -test(It first, It last) -{ - typedef typename std::iterator_traits::value_type charT; - typedef std::basic_string, test_allocator > S; - typedef typename S::allocator_type A; - S s2(first, last); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == static_cast(std::distance(first, last))); - unsigned i = 0; - for (It it = first; it != last; ++it, ++i) - assert(s2[i] == *it); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(It first, It last) { + typedef typename std::iterator_traits::value_type charT; + typedef std::basic_string, test_allocator > S; + typedef typename S::allocator_type A; + S s2(first, last); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == static_cast(std::distance(first, last))); + unsigned i = 0; + for (It it = first; it != last; ++it, ++i) + assert(s2[i] == *it); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); } template -void -test(It first, It last, const A& a) -{ - typedef typename std::iterator_traits::value_type charT; - typedef std::basic_string, A> S; - S s2(first, last, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == static_cast(std::distance(first, last))); - unsigned i = 0; - for (It it = first; it != last; ++it, ++i) - assert(s2[i] == *it); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(It first, It last, const A& a) { + typedef typename std::iterator_traits::value_type charT; + typedef std::basic_string, A> S; + S s2(first, last, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == static_cast(std::distance(first, last))); + unsigned i = 0; + for (It it = first; it != last; ++it, ++i) + assert(s2[i] == *it); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; const char* s = "12345678901234567890123456789012345678901234567890"; @@ -125,6 +121,16 @@ std::allocator >::value), ""); } + 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/move.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp @@ -20,27 +20,28 @@ #include "min_allocator.h" template -void -test(S s0) -{ - S s1 = s0; - S s2 = std::move(s0); - LIBCPP_ASSERT(s2.__invariants()); +TEST_CONSTEXPR_CXX20 void test(S s0) { + S s1 = s0; + S s2 = std::move(s0); + LIBCPP_ASSERT(s2.__invariants()); + if (TEST_IS_CONSTANT_EVALUATED) + LIBCPP_ASSERT(!s0.__invariants()); + else LIBCPP_ASSERT(s0.__invariants()); - assert(s2 == s1); - assert(s2.capacity() >= s2.size()); - assert(s2.get_allocator() == s1.get_allocator()); + 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))); test(S("1", A(5))); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7))); - } + } { typedef min_allocator A; typedef std::basic_string, A> S; @@ -49,5 +50,16 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A())); } + 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/move_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp @@ -19,24 +19,21 @@ #include "test_allocator.h" #include "min_allocator.h" - template -void -test(S s0, const typename S::allocator_type& a) -{ - S s1 = s0; - S s2(std::move(s0), a); - LIBCPP_ASSERT(s2.__invariants()); +TEST_CONSTEXPR_CXX20 void test(S s0, const typename S::allocator_type& a) { + S s1 = s0; + S s2(std::move(s0), a); + LIBCPP_ASSERT(s2.__invariants()); + if (!TEST_IS_CONSTANT_EVALUATED) LIBCPP_ASSERT(s0.__invariants()); - assert(s2 == s1); - assert(s2.capacity() >= s2.size()); - assert(s2.get_allocator() == a); + assert(s2 == s1); + assert(s2.capacity() >= s2.size()); + assert(s2.get_allocator() == a); } - -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; typedef std::basic_string, A> S; #if TEST_STD_VER > 14 @@ -48,8 +45,9 @@ test(S("1"), A(5)); test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); } - - int alloc_count = test_alloc_base::alloc_count; + int alloc_count; + if (!TEST_IS_CONSTANT_EVALUATED) + alloc_count = test_alloc_base::alloc_count; { typedef test_allocator A; typedef std::basic_string, A> S; @@ -61,7 +59,8 @@ S s1 ( "Twas brillig, and the slivy toves did gyre and gymbal in the wabe" ); S s2 (std::move(s1), A(1)); } - assert ( test_alloc_base::alloc_count == alloc_count ); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(test_alloc_base::alloc_count == alloc_count); { typedef min_allocator A; typedef std::basic_string, A> S; @@ -75,5 +74,16 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); } + 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/move_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp @@ -21,20 +21,21 @@ #include "min_allocator.h" template -void -test(S s1, S s2) -{ - S s0 = s2; - s1 = std::move(s2); - LIBCPP_ASSERT(s1.__invariants()); +TEST_CONSTEXPR_CXX20 void test(S s1, S s2) { + S s0 = s2; + s1 = std::move(s2); + LIBCPP_ASSERT(s1.__invariants()); + if (TEST_IS_CONSTANT_EVALUATED) + LIBCPP_ASSERT(!s2.__invariants()); + else LIBCPP_ASSERT(s2.__invariants()); - assert(s1 == s0); - assert(s1.capacity() >= s1.size()); + assert(s1 == s0); + 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()); @@ -51,7 +52,7 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890"), S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); - } + } { typedef std::basic_string, min_allocator> S; test(S(), S()); @@ -71,5 +72,16 @@ S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } + 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/pointer_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp @@ -21,39 +21,35 @@ #include "min_allocator.h" template -void -test(const charT* s) -{ - typedef std::basic_string, test_allocator > S; - typedef typename S::traits_type T; - typedef typename S::allocator_type A; - std::size_t n = T::length(s); - S s2(s); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - assert(T::compare(s2.data(), s, n) == 0); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(const charT* s) { + typedef std::basic_string, test_allocator > S; + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + std::size_t n = T::length(s); + S s2(s); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + assert(T::compare(s2.data(), s, n) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); } template -void -test(const charT* s, const A& a) -{ - typedef std::basic_string, A> S; - typedef typename S::traits_type T; - std::size_t n = T::length(s); - S s2(s, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - assert(T::compare(s2.data(), s, n) == 0); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(const charT* s, const A& a) { + typedef std::basic_string, A> S; + typedef typename S::traits_type T; + std::size_t n = T::length(s); + S s2(s, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + assert(T::compare(s2.data(), s, n) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; test(""); @@ -86,5 +82,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/pointer_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp @@ -18,20 +18,18 @@ #include "min_allocator.h" template -void -test(S s1, const typename S::value_type* s2) -{ - typedef typename S::traits_type T; - s1 = s2; - LIBCPP_ASSERT(s1.__invariants()); - assert(s1.size() == T::length(s2)); - assert(T::compare(s1.data(), s2, s1.size()) == 0); - assert(s1.capacity() >= s1.size()); +TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::value_type* s2) { + typedef typename S::traits_type T; + s1 = s2; + LIBCPP_ASSERT(s1.__invariants()); + assert(s1.size() == T::length(s2)); + assert(T::compare(s1.data(), s2, s1.size()) == 0); + assert(s1.capacity() >= s1.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S(), ""); test(S("1"), ""); @@ -48,7 +46,7 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890"), "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); - } + } #if TEST_STD_VER >= 11 { typedef std::basic_string, min_allocator> S; @@ -70,5 +68,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/pointer_size_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp @@ -20,37 +20,33 @@ #include "min_allocator.h" template -void -test(const charT* s, unsigned n) -{ - typedef std::basic_string, test_allocator > S; - typedef typename S::traits_type T; - typedef typename S::allocator_type A; - S s2(s, n); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - assert(T::compare(s2.data(), s, n) == 0); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(const charT* s, unsigned n) { + typedef std::basic_string, test_allocator > S; + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + S s2(s, n); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + assert(T::compare(s2.data(), s, n) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); } template -void -test(const charT* s, unsigned n, const A& a) -{ - typedef std::basic_string, A> S; - typedef typename S::traits_type T; - S s2(s, n, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - assert(T::compare(s2.data(), s, n) == 0); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(const charT* s, unsigned n, const A& a) { + typedef std::basic_string, A> S; + typedef typename S::traits_type T; + S s2(s, n, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + assert(T::compare(s2.data(), s, n) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; test("", 0); @@ -91,5 +87,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/size_char_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp @@ -21,68 +21,60 @@ #include "min_allocator.h" template -void -test(unsigned n, charT c) -{ - typedef std::basic_string, test_allocator > S; - typedef typename S::allocator_type A; - S s2(n, c); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - for (unsigned i = 0; i < n; ++i) - assert(s2[i] == c); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(unsigned n, charT c) { + typedef std::basic_string, test_allocator > S; + typedef typename S::allocator_type A; + S s2(n, c); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + for (unsigned i = 0; i < n; ++i) + assert(s2[i] == c); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); } template -void -test(unsigned n, charT c, const A& a) -{ - typedef std::basic_string, A> S; - S s2(n, c, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == n); - for (unsigned i = 0; i < n; ++i) - assert(s2[i] == c); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(unsigned n, charT c, const A& a) { + typedef std::basic_string, A> S; + S s2(n, c, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == n); + for (unsigned i = 0; i < n; ++i) + assert(s2[i] == c); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); } template -void -test(Tp n, Tp c) -{ - typedef char charT; - typedef std::basic_string, test_allocator > S; - typedef typename S::allocator_type A; - S s2(n, c); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == static_cast(n)); - for (int i = 0; i < n; ++i) - assert(s2[i] == c); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(Tp n, Tp c) { + typedef char charT; + typedef std::basic_string, test_allocator > S; + typedef typename S::allocator_type A; + S s2(n, c); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == static_cast(n)); + for (int i = 0; i < n; ++i) + assert(s2[i] == c); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); } template -void -test(Tp n, Tp c, const A& a) -{ - typedef char charT; - typedef std::basic_string, A> S; - S s2(n, c, a); - LIBCPP_ASSERT(s2.__invariants()); - assert(s2.size() == static_cast(n)); - for (int i = 0; i < n; ++i) - assert(s2[i] == c); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); +TEST_CONSTEXPR_CXX20 void test(Tp n, Tp c, const A& a) { + typedef char charT; + typedef std::basic_string, A> S; + S s2(n, c, a); + LIBCPP_ASSERT(s2.__invariants()); + assert(s2.size() == static_cast(n)); + for (int i = 0; i < n; ++i) + assert(s2[i] == c); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; test(0, 'a'); @@ -120,6 +112,16 @@ test(static_cast(100), static_cast(65), A()); } #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/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp @@ -21,12 +21,10 @@ #include "min_allocator.h" template -void -test(std::basic_string_view sv) -{ - typedef std::basic_string, test_allocator > S; - typedef typename S::traits_type T; - typedef typename S::allocator_type A; +TEST_CONSTEXPR_CXX20 void test(std::basic_string_view sv) { + typedef std::basic_string, test_allocator > S; + typedef typename S::traits_type T; + typedef typename S::allocator_type A; { S s2(sv); LIBCPP_ASSERT(s2.__invariants()); @@ -47,11 +45,9 @@ } template -void -test(std::basic_string_view sv, const A& a) -{ - typedef std::basic_string, A> S; - typedef typename S::traits_type T; +TEST_CONSTEXPR_CXX20 void test(std::basic_string_view sv, const A& a) { + typedef std::basic_string, A> S; + typedef typename S::traits_type T; { S s2(sv, a); LIBCPP_ASSERT(s2.__invariants()); @@ -71,9 +67,9 @@ } } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; typedef std::basic_string_view > SV; @@ -108,5 +104,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/string_view_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp @@ -17,20 +17,18 @@ #include "min_allocator.h" template -void -test(S s1, SV sv) -{ - typedef typename S::traits_type T; - s1 = sv; - LIBCPP_ASSERT(s1.__invariants()); - assert(s1.size() == sv.size()); - assert(T::compare(s1.data(), sv.data(), s1.size()) == 0); - assert(s1.capacity() >= s1.size()); +TEST_CONSTEXPR_CXX20 void test(S s1, SV sv) { + typedef typename S::traits_type T; + s1 = sv; + LIBCPP_ASSERT(s1.__invariants()); + assert(s1.size() == sv.size()); + assert(T::compare(s1.data(), sv.data(), s1.size()) == 0); + assert(s1.capacity() >= s1.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; typedef std::string_view SV; test(S(), SV("")); @@ -48,7 +46,7 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890"), SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); - } + } #if TEST_STD_VER >= 11 { typedef std::basic_string, min_allocator> S; @@ -71,5 +69,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/substr.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp @@ -27,122 +27,110 @@ #include "test_allocator.h" #include "min_allocator.h" +#ifndef __cpp_lib_constexpr_vector +# define __cpp_lib_constexpr_vector 0L +#endif + template -void -test(S str, unsigned pos) -{ - typedef typename S::traits_type T; - typedef typename S::allocator_type A; - - if (pos <= str.size()) - { - S s2(str, pos); - LIBCPP_ASSERT(s2.__invariants()); - typename S::size_type rlen = str.size() - pos; - assert(s2.size() == rlen); - assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); - } +TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos) { + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + + if (pos <= str.size()) { + S s2(str, pos); + LIBCPP_ASSERT(s2.__invariants()); + typename S::size_type rlen = str.size() - pos; + assert(s2.size() == rlen); + assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { - try - { - S s2(str, pos); - assert(false); - } - catch (std::out_of_range&) - { - assert(pos > str.size()); - } + else if (!TEST_IS_CONSTANT_EVALUATED) { + try { + S s2(str, pos); + assert(false); + } catch (std::out_of_range&) { + assert(pos > str.size()); } + } #endif } template -void -test(S str, unsigned pos, unsigned n) -{ - typedef typename S::traits_type T; - typedef typename S::allocator_type A; - if (pos <= str.size()) - { - S s2(str, pos, n); - LIBCPP_ASSERT(s2.__invariants()); - typename S::size_type rlen = std::min(str.size() - pos, n); - assert(s2.size() == rlen); - assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); - assert(s2.get_allocator() == A()); - assert(s2.capacity() >= s2.size()); - } +TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n) { + typedef typename S::traits_type T; + typedef typename S::allocator_type A; + if (pos <= str.size()) { + S s2(str, pos, n); + LIBCPP_ASSERT(s2.__invariants()); + typename S::size_type rlen = std::min(str.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); + assert(s2.get_allocator() == A()); + assert(s2.capacity() >= s2.size()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { - try - { - S s2(str, pos, n); - assert(false); - } - catch (std::out_of_range&) - { - assert(pos > str.size()); - } + else if (!TEST_IS_CONSTANT_EVALUATED) { + try { + S s2(str, pos, n); + assert(false); + } catch (std::out_of_range&) { + assert(pos > str.size()); } + } #endif } template -void -test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) -{ - typedef typename S::traits_type T; - - if (pos <= str.size()) - { - S s2(str, pos, n, a); - LIBCPP_ASSERT(s2.__invariants()); - typename S::size_type rlen = std::min(str.size() - pos, n); - assert(s2.size() == rlen); - assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); - assert(s2.get_allocator() == a); - assert(s2.capacity() >= s2.size()); - } +TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) { + typedef typename S::traits_type T; + + if (pos <= str.size()) { + S s2(str, pos, n, a); + LIBCPP_ASSERT(s2.__invariants()); + typename S::size_type rlen = std::min(str.size() - pos, n); + assert(s2.size() == rlen); + assert(T::compare(s2.data(), str.data() + pos, rlen) == 0); + assert(s2.get_allocator() == a); + assert(s2.capacity() >= s2.size()); + } #ifndef TEST_HAS_NO_EXCEPTIONS - else - { - try - { - S s2(str, pos, n, a); - assert(false); - } - catch (std::out_of_range&) - { - assert(pos > str.size()); - } + else if (!TEST_IS_CONSTANT_EVALUATED) { + try { + S s2(str, pos, n, a); + assert(false); + } catch (std::out_of_range&) { + assert(pos > str.size()); } + } #endif } #if TEST_STD_VER >= 11 -#ifndef TEST_HAS_NO_EXCEPTIONS -void test2583() -{ // LWG #2583 - typedef std::basic_string, test_allocator > StringA; - std::vector>> vs; - StringA s{"1234"}; - vs.emplace_back(s, 2); - - try { vs.emplace_back(s, 5); } - catch (const std::out_of_range&) { return; } - assert(false); +# ifndef TEST_HAS_NO_EXCEPTIONS +# if __cpp_lib_constexpr_vector >= 201907L +TEST_CONSTEXPR_CXX20 +# endif +void test2583() { // LWG #2583 + typedef std::basic_string, test_allocator > StringA; + std::vector > > vs; + StringA s{"1234"}; + vs.emplace_back(s, 2); + + try { + vs.emplace_back(s, 5); + } catch (const std::out_of_range&) { + return; + } + assert(false); } -#endif +# endif #endif -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef test_allocator A; typedef std::basic_string, A> S; @@ -179,9 +167,9 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1, A(8)); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8)); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8)); - } + } #if TEST_STD_VER >= 11 - { + { typedef min_allocator A; typedef std::basic_string, A> S; @@ -218,11 +206,23 @@ test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1, A()); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A()); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A()); - } + } -#ifndef TEST_HAS_NO_EXCEPTIONS +# ifndef TEST_HAS_NO_EXCEPTIONS + if (!TEST_IS_CONSTANT_EVALUATED || __cpp_lib_constexpr_vector >= 201907L) test2583(); +# endif #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.contains/contains.char.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp @@ -16,26 +16,28 @@ #include "test_macros.h" -void test() -{ - using S = std::string; +constexpr bool test() { + using S = std::string; - S s1 {}; - S s2 {"abcde", 5}; + S s1{}; + S s2{"abcde", 5}; - ASSERT_NOEXCEPT(s1.contains('e')); + ASSERT_NOEXCEPT(s1.contains('e')); - assert(!s1.contains('c')); - assert(!s1.contains('e')); - assert(!s1.contains('x')); - assert( s2.contains('c')); - assert( s2.contains('e')); - assert(!s2.contains('x')); + assert(!s1.contains('c')); + assert(!s1.contains('e')); + assert(!s1.contains('x')); + assert(s2.contains('c')); + assert(s2.contains('e')); + assert(!s2.contains('x')); + + return true; } -int main(int, char**) -{ - test(); +int main(int, char**) { + + test(); + static_assert(test()); - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp @@ -16,56 +16,58 @@ #include "test_macros.h" -void test() -{ - using S = std::string; +constexpr bool test() { + using S = std::string; - const char* s = "abcde"; - S s0; - S s1 {s + 4, 1}; - S s3 {s + 2, 3}; - S sNot {"xyz", 3}; + const char* s = "abcde"; + S s0; + S s1{s + 4, 1}; + S s3{s + 2, 3}; + S sNot{"xyz", 3}; - assert(s0.contains("")); - assert(!s0.contains("e")); + assert(s0.contains("")); + assert(!s0.contains("e")); - assert( s1.contains("")); - assert(!s1.contains("d")); - assert( s1.contains("e")); - assert(!s1.contains("de")); - assert(!s1.contains("cd")); - assert(!s1.contains("cde")); - assert(!s1.contains("bcde")); - assert(!s1.contains("abcde")); - assert(!s1.contains("xyz")); + assert(s1.contains("")); + assert(!s1.contains("d")); + assert(s1.contains("e")); + assert(!s1.contains("de")); + assert(!s1.contains("cd")); + assert(!s1.contains("cde")); + assert(!s1.contains("bcde")); + assert(!s1.contains("abcde")); + assert(!s1.contains("xyz")); - assert( s3.contains("")); - assert( s3.contains("d")); - assert( s3.contains("e")); - assert( s3.contains("de")); - assert( s3.contains("cd")); - assert(!s3.contains("ce")); - assert( s3.contains("cde")); - assert(!s3.contains("edc")); - assert(!s3.contains("bcde")); - assert(!s3.contains("abcde")); - assert(!s3.contains("xyz")); + assert(s3.contains("")); + assert(s3.contains("d")); + assert(s3.contains("e")); + assert(s3.contains("de")); + assert(s3.contains("cd")); + assert(!s3.contains("ce")); + assert(s3.contains("cde")); + assert(!s3.contains("edc")); + assert(!s3.contains("bcde")); + assert(!s3.contains("abcde")); + assert(!s3.contains("xyz")); - assert( sNot.contains("")); - assert(!sNot.contains("d")); - assert(!sNot.contains("e")); - assert(!sNot.contains("de")); - assert(!sNot.contains("cd")); - assert(!sNot.contains("cde")); - assert(!sNot.contains("bcde")); - assert(!sNot.contains("abcde")); - assert( sNot.contains("xyz")); - assert(!sNot.contains("zyx")); + assert(sNot.contains("")); + assert(!sNot.contains("d")); + assert(!sNot.contains("e")); + assert(!sNot.contains("de")); + assert(!sNot.contains("cd")); + assert(!sNot.contains("cde")); + assert(!sNot.contains("bcde")); + assert(!sNot.contains("abcde")); + assert(sNot.contains("xyz")); + assert(!sNot.contains("zyx")); + + return true; } -int main(int, char**) -{ - test(); +int main(int, char**) { + + test(); + static_assert(test()); - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp @@ -16,77 +16,79 @@ #include "test_macros.h" -void test() -{ - using S = std::string; - using SV = std::string_view; - - const char* s = "abcde"; - S s0; - S s1 {s + 1, 1}; - S s3 {s + 1, 3}; - S s5 {s , 5}; - S sNot {"xyz", 3}; - - SV sv0; - SV sv1 {s + 1, 1}; - SV sv2 {s + 1, 2}; - SV sv3 {s + 1, 3}; - SV sv4 {s + 1, 4}; - SV sv5 {s , 5}; - SV svNot {"xyz", 3}; - SV svNot2 {"bd" , 2}; - SV svNot3 {"dcb", 3}; - - ASSERT_NOEXCEPT(s0.contains(sv0)); - - assert( s0.contains(sv0)); - assert(!s0.contains(sv1)); - - assert( s1.contains(sv0)); - assert( s1.contains(sv1)); - assert(!s1.contains(sv2)); - assert(!s1.contains(sv3)); - assert(!s1.contains(sv4)); - assert(!s1.contains(sv5)); - assert(!s1.contains(svNot)); - assert(!s1.contains(svNot2)); - assert(!s1.contains(svNot3)); - - assert( s3.contains(sv0)); - assert( s3.contains(sv1)); - assert( s3.contains(sv2)); - assert( s3.contains(sv3)); - assert(!s3.contains(sv4)); - assert(!s3.contains(sv5)); - assert(!s3.contains(svNot)); - assert(!s3.contains(svNot2)); - assert(!s3.contains(svNot3)); - - assert( s5.contains(sv0)); - assert( s5.contains(sv1)); - assert( s5.contains(sv2)); - assert( s5.contains(sv3)); - assert( s5.contains(sv4)); - assert( s5.contains(sv5)); - assert(!s5.contains(svNot)); - assert(!s5.contains(svNot2)); - assert(!s5.contains(svNot3)); - - assert( sNot.contains(sv0)); - assert(!sNot.contains(sv1)); - assert(!sNot.contains(sv2)); - assert(!sNot.contains(sv3)); - assert(!sNot.contains(sv4)); - assert(!sNot.contains(sv5)); - assert( sNot.contains(svNot)); - assert(!sNot.contains(svNot2)); - assert(!sNot.contains(svNot3)); +constexpr bool test() { + using S = std::string; + using SV = std::string_view; + + const char* s = "abcde"; + S s0; + S s1{s + 1, 1}; + S s3{s + 1, 3}; + S s5{s, 5}; + S sNot{"xyz", 3}; + + SV sv0; + SV sv1{s + 1, 1}; + SV sv2{s + 1, 2}; + SV sv3{s + 1, 3}; + SV sv4{s + 1, 4}; + SV sv5{s, 5}; + SV svNot{"xyz", 3}; + SV svNot2{"bd", 2}; + SV svNot3{"dcb", 3}; + + ASSERT_NOEXCEPT(s0.contains(sv0)); + + assert(s0.contains(sv0)); + assert(!s0.contains(sv1)); + + assert(s1.contains(sv0)); + assert(s1.contains(sv1)); + assert(!s1.contains(sv2)); + assert(!s1.contains(sv3)); + assert(!s1.contains(sv4)); + assert(!s1.contains(sv5)); + assert(!s1.contains(svNot)); + assert(!s1.contains(svNot2)); + assert(!s1.contains(svNot3)); + + assert(s3.contains(sv0)); + assert(s3.contains(sv1)); + assert(s3.contains(sv2)); + assert(s3.contains(sv3)); + assert(!s3.contains(sv4)); + assert(!s3.contains(sv5)); + assert(!s3.contains(svNot)); + assert(!s3.contains(svNot2)); + assert(!s3.contains(svNot3)); + + assert(s5.contains(sv0)); + assert(s5.contains(sv1)); + assert(s5.contains(sv2)); + assert(s5.contains(sv3)); + assert(s5.contains(sv4)); + assert(s5.contains(sv5)); + assert(!s5.contains(svNot)); + assert(!s5.contains(svNot2)); + assert(!s5.contains(svNot3)); + + assert(sNot.contains(sv0)); + assert(!sNot.contains(sv1)); + assert(!sNot.contains(sv2)); + assert(!sNot.contains(sv3)); + assert(!sNot.contains(sv4)); + assert(!sNot.contains(sv5)); + assert(sNot.contains(svNot)); + assert(!sNot.contains(svNot2)); + assert(!sNot.contains(svNot3)); + + return true; } -int main(int, char**) -{ - test(); +int main(int, char**) { + + test(); + static_assert(test()); - return 0; + return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp @@ -16,9 +16,8 @@ #include "test_macros.h" -int main(int, char**) -{ - { +constexpr bool test() { + { typedef std::string S; S s1 {}; S s2 { "abcde", 5 }; @@ -29,7 +28,15 @@ assert (!s1.ends_with('x')); assert ( s2.ends_with('e')); assert (!s2.ends_with('x')); - } + } + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp @@ -16,9 +16,8 @@ #include "test_macros.h" -int main(int, char**) -{ - { +constexpr bool test() { + { typedef std::string S; const char *s = "abcde"; @@ -58,7 +57,15 @@ assert (!sNot.ends_with("bcde")); assert (!sNot.ends_with("abcde")); assert ( sNot.ends_with("def")); - } + } + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp @@ -16,9 +16,8 @@ #include "test_macros.h" -int main(int, char**) -{ - { +constexpr bool test() { + { typedef std::string S; typedef std::string_view SV; const char *s = "abcde"; @@ -67,7 +66,15 @@ assert (!sNot.ends_with(sv4)); assert (!sNot.ends_with(sv5)); assert ( sNot.ends_with(svNot)); - } + } + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp @@ -18,22 +18,19 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - typename S::iterator b = s.begin(); - typename S::const_iterator cb = cs.begin(); - if (!s.empty()) - { - assert(*b == s[0]); - } - assert(b == cb); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + typename S::iterator b = s.begin(); + typename S::const_iterator cb = cs.begin(); + if (!s.empty()) { + assert(*b == s[0]); + } + assert(b == cb); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -46,5 +43,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.iterators/cbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp @@ -17,20 +17,17 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - typename S::const_iterator cb = s.cbegin(); - if (!s.empty()) - { - assert(*cb == s[0]); - } - assert(cb == s.begin()); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + typename S::const_iterator cb = s.cbegin(); + if (!s.empty()) { + assert(*cb == s[0]); + } + assert(cb == s.begin()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -43,5 +40,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.iterators/cend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp @@ -17,16 +17,14 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - typename S::const_iterator ce = s.cend(); - assert(ce == s.end()); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + typename S::const_iterator ce = s.cend(); + assert(ce == s.end()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -39,5 +37,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.iterators/crbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp @@ -17,20 +17,17 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - typename S::const_reverse_iterator cb = s.crbegin(); - if (!s.empty()) - { - assert(*cb == s.back()); - } - assert(cb == s.rbegin()); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + typename S::const_reverse_iterator cb = s.crbegin(); + if (!s.empty()) { + assert(*cb == s.back()); + } + assert(cb == s.rbegin()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -43,5 +40,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.iterators/crend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp @@ -17,16 +17,14 @@ #include "min_allocator.h" template -void -test(const S& s) -{ - typename S::const_reverse_iterator ce = s.crend(); - assert(ce == s.rend()); +TEST_CONSTEXPR_CXX20 void test(const S& s) { + typename S::const_reverse_iterator ce = s.crend(); + assert(ce == s.rend()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -39,5 +37,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.iterators/end.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp @@ -19,24 +19,21 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - typename S::iterator e = s.end(); - typename S::const_iterator ce = cs.end(); - if (s.empty()) - { - assert(e == s.begin()); - assert(ce == cs.begin()); - } - assert(static_cast(e - s.begin()) == s.size()); - assert(static_cast(ce - cs.begin()) == cs.size()); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + typename S::iterator e = s.end(); + typename S::const_iterator ce = cs.end(); + if (s.empty()) { + assert(e == s.begin()); + assert(ce == cs.begin()); + } + assert(static_cast(e - s.begin()) == s.size()); + assert(static_cast(ce - cs.begin()) == cs.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -49,5 +46,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.iterators/iterators.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp @@ -22,39 +22,38 @@ #include "test_macros.h" -template -void test() -{ - { // N3644 testing - typename C::iterator ii1{}, ii2{}; - typename C::iterator ii4 = ii1; - typename C::const_iterator cii{}; - assert ( ii1 == ii2 ); - assert ( ii1 == ii4 ); - - assert (!(ii1 != ii2 )); - - assert ( (ii1 == cii )); - assert ( (cii == ii1 )); - assert (!(ii1 != cii )); - assert (!(cii != ii1 )); - assert (!(ii1 < cii )); - assert (!(cii < ii1 )); - assert ( (ii1 <= cii )); - assert ( (cii <= ii1 )); - assert (!(ii1 > cii )); - assert (!(cii > ii1 )); - assert ( (ii1 >= cii )); - assert ( (cii >= ii1 )); - assert (cii - ii1 == 0); - assert (ii1 - cii == 0); - } +template +TEST_CONSTEXPR_CXX20 void test() { + { // N3644 testing + typename C::iterator ii1{}, ii2{}; + typename C::iterator ii4 = ii1; + typename C::const_iterator cii{}; + assert(ii1 == ii2); + assert(ii1 == ii4); + + assert(!(ii1 != ii2)); + + assert((ii1 == cii)); + assert((cii == ii1)); + assert(!(ii1 != cii)); + assert(!(cii != ii1)); + assert(!(ii1 < cii)); + assert(!(cii < ii1)); + assert((ii1 <= cii)); + assert((cii <= ii1)); + assert(!(ii1 > cii)); + assert(!(cii > ii1)); + assert((ii1 >= cii)); + assert((cii >= ii1)); + assert(cii - ii1 == 0); + assert(ii1 - cii == 0); + } } -int main(int, char**) -{ - test(); - test(); +TEST_CONSTEXPR_CXX20 +bool test() { + test(); + test(); #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L test(); @@ -63,5 +62,16 @@ test(); test(); - return 0; + 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.iterators/rbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp @@ -18,22 +18,19 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - typename S::reverse_iterator b = s.rbegin(); - typename S::const_reverse_iterator cb = cs.rbegin(); - if (!s.empty()) - { - assert(*b == s.back()); - } - assert(b == cb); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + typename S::reverse_iterator b = s.rbegin(); + typename S::const_reverse_iterator cb = cs.rbegin(); + if (!s.empty()) { + assert(*b == s.back()); + } + assert(b == cb); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -46,5 +43,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.iterators/rend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp @@ -19,24 +19,21 @@ #include "min_allocator.h" template -void -test(S s) -{ - const S& cs = s; - typename S::reverse_iterator e = s.rend(); - typename S::const_reverse_iterator ce = cs.rend(); - if (s.empty()) - { - assert(e == s.rbegin()); - assert(ce == cs.rbegin()); - } - assert(static_cast(e - s.rbegin()) == s.size()); - assert(static_cast(ce - cs.rbegin()) == cs.size()); +TEST_CONSTEXPR_CXX20 void test(S s) { + const S& cs = s; + typename S::reverse_iterator e = s.rend(); + typename S::const_reverse_iterator ce = cs.rend(); + if (s.empty()) { + assert(e == s.rbegin()); + assert(ce == cs.rbegin()); + } + assert(static_cast(e - s.rbegin()) == s.size()); + assert(static_cast(ce - cs.rbegin()) == cs.size()); } -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX20 +bool test() { + { typedef std::string S; test(S()); test(S("123")); @@ -49,5 +46,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 @@ -86,21 +86,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 +121,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 +178,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);} diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -10,6 +10,8 @@ #ifndef SUPPORT_TEST_MACROS_HPP #define SUPPORT_TEST_MACROS_HPP +#include + // Attempt to get STL specific macros like _LIBCPP_VERSION using the most // minimal header possible. If we're testing libc++, we should use `<__config>`. // If <__config> isn't available, fall back to . @@ -145,6 +147,12 @@ # define TEST_THROW_SPEC(...) throw(__VA_ARGS__) #endif +#if __cpp_lib_is_constant_evaluated >= 201811L +# define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated() +#else +# define TEST_IS_CONSTANT_EVALUATED false +#endif + #if TEST_STD_VER >= 14 # define TEST_CONSTEXPR_CXX14 constexpr #else