diff options
Diffstat (limited to 'lib/libcxx/include/string')
| -rw-r--r-- | lib/libcxx/include/string | 614 |
1 files changed, 271 insertions, 343 deletions
diff --git a/lib/libcxx/include/string b/lib/libcxx/include/string index 4159ea5803..fd6a7424c8 100644 --- a/lib/libcxx/include/string +++ b/lib/libcxx/include/string @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- string -----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -158,6 +158,9 @@ public: void resize(size_type n, value_type c); void resize(size_type n); + template<class Operation> + constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 + void reserve(size_type res_arg); void reserve(); // deprecated in C++20 void shrink_to_fit(); @@ -524,7 +527,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #include <cstdio> // EOF #include <cstdlib> #include <cstring> -#include <cwchar> #include <initializer_list> #include <iosfwd> #include <iterator> @@ -535,6 +537,10 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #include <utility> #include <version> +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# include <cwchar> +#endif + #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS # include <cstdint> #endif @@ -612,30 +618,6 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) -template <bool> -class _LIBCPP_TEMPLATE_VIS __basic_string_common -{ -protected: - _LIBCPP_NORETURN void __throw_length_error() const; - _LIBCPP_NORETURN void __throw_out_of_range() const; -}; - -template <bool __b> -void -__basic_string_common<__b>::__throw_length_error() const -{ - _VSTD::__throw_length_error("basic_string"); -} - -template <bool __b> -void -__basic_string_common<__b>::__throw_out_of_range() const -{ - _VSTD::__throw_out_of_range("basic_string"); -} - -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>) - template <class _Iter> struct __string_is_trivial_iterator : public false_type {}; @@ -675,7 +657,7 @@ typedef basic_string<char8_t> u8string; #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef basic_string<char16_t> u16string; typedef basic_string<char32_t> u32string; -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +#endif template<class _CharT, class _Traits, class _Allocator> class @@ -688,7 +670,6 @@ class _LIBCPP_PREFERRED_NAME(u32string) #endif basic_string - : private __basic_string_common<true> { public: typedef basic_string __self; @@ -832,17 +813,15 @@ public: basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG - template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> > + template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > _LIBCPP_INLINE_VISIBILITY 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)); -# if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -# endif + _VSTD::__debug_db_insert_c(this); } - template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> > + template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, const _Allocator& __a); @@ -857,7 +836,7 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c); - template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> > + template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c, const _Allocator& __a); @@ -867,24 +846,24 @@ public: basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()); - template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > + template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()); - template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && + template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t); - template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > + template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t, const allocator_type& __a); - template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> > + template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); - template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> > + template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG @@ -901,7 +880,7 @@ public: basic_string& operator=(const basic_string& __str); - template <class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > + template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > basic_string& operator=(const _Tp& __t) {__self_view __sv = __t; return assign(__sv);} @@ -983,6 +962,16 @@ public: _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} void reserve(size_type __requested_capacity); + +#if _LIBCPP_STD_VER > 20 + template <class _Op> + _LIBCPP_HIDE_FROM_ABI constexpr + void resize_and_overwrite(size_type __n, _Op __op) { + __resize_default_init(__n); + __erase_to_end(_VSTD::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); + } +#endif + _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY @@ -1004,7 +993,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string >::value, @@ -1022,7 +1011,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf< + __enable_if_t< __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& @@ -1032,7 +1021,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, @@ -1048,7 +1037,7 @@ public: template<class _InputIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string& @@ -1061,7 +1050,7 @@ public: } template<class _ForwardIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string& @@ -1084,7 +1073,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& @@ -1101,7 +1090,7 @@ public: basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, @@ -1113,7 +1102,7 @@ public: basic_string& assign(size_type __n, value_type __c); template<class _InputIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string& @@ -1121,7 +1110,7 @@ public: assign(_InputIterator __first, _InputIterator __last); template<class _ForwardIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string& @@ -1137,7 +1126,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& @@ -1147,7 +1136,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& @@ -1162,7 +1151,7 @@ public: iterator insert(const_iterator __pos, size_type __n, value_type __c); template<class _InputIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, iterator @@ -1170,7 +1159,7 @@ public: insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); template<class _ForwardIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, iterator @@ -1193,7 +1182,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& @@ -1202,7 +1191,7 @@ public: basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& @@ -1216,7 +1205,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& @@ -1231,7 +1220,7 @@ public: basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c); template<class _InputIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, basic_string& @@ -1273,7 +1262,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1289,7 +1278,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1305,7 +1294,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1322,7 +1311,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1339,7 +1328,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1356,7 +1345,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type @@ -1373,7 +1362,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int @@ -1382,7 +1371,7 @@ public: template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int @@ -1395,7 +1384,7 @@ public: template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, int @@ -1406,28 +1395,28 @@ public: int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; #if _LIBCPP_STD_VER > 17 - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool starts_with(__self_view __sv) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool starts_with(__self_view __sv) const noexcept { return __self_view(data(), size()).starts_with(__sv); } - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool starts_with(value_type __c) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool starts_with(value_type __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool starts_with(const value_type* __s) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool starts_with(const value_type* __s) const noexcept { return starts_with(__self_view(__s)); } - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool ends_with(__self_view __sv) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool ends_with(__self_view __sv) const noexcept { return __self_view(data(), size()).ends_with( __sv); } - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool ends_with(value_type __c) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool ends_with(value_type __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool ends_with(const value_type* __s) const _NOEXCEPT + constexpr _LIBCPP_INLINE_VISIBILITY + bool ends_with(const value_type* __s) const noexcept { return ends_with(__self_view(__s)); } #endif @@ -1465,6 +1454,11 @@ public: #endif // _LIBCPP_DEBUG_LEVEL == 2 private: + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { + // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly + return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); + } + _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() _NOEXCEPT {return __r_.second();} @@ -1591,7 +1585,7 @@ private: template <class _InputIterator> inline - _EnableIf + __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value > @@ -1599,7 +1593,7 @@ private: template <class _ForwardIterator> inline - _EnableIf + __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > @@ -1705,6 +1699,13 @@ private: return *this; } + _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { + __set_size(__newsz); + __invalidate_iterators_past(__newsz); + traits_type::assign(__p[__newsz], value_type()); + return *this; + } + _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); @@ -1717,20 +1718,12 @@ private: _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_length_error(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_length_error("basic_string"); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_out_of_range(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_out_of_range("basic_string"); } friend basic_string operator+<>(const basic_string&, const basic_string&); @@ -1743,20 +1736,24 @@ private: // These declarations must appear before any functions are implicitly used // so that they have the correct visibility specifier. #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION -_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) -_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) +# endif #else -_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) -_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) +# endif #endif -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#if _LIBCPP_STD_VER >= 17 template<class _InputIterator, class _CharT = __iter_value_type<_InputIterator>, class _Allocator = allocator<_CharT>, - class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>, - class = _EnableIf<__is_allocator<_Allocator>::value> + class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value> > basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; @@ -1764,7 +1761,7 @@ basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) template<class _CharT, class _Traits, class _Allocator = allocator<_CharT>, - class = _EnableIf<__is_allocator<_Allocator>::value> + class = enable_if_t<__is_allocator<_Allocator>::value> > explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>; @@ -1772,7 +1769,7 @@ explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _A template<class _CharT, class _Traits, class _Allocator = allocator<_CharT>, - class = _EnableIf<__is_allocator<_Allocator>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value>, class _Sz = typename allocator_traits<_Allocator>::size_type > basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) @@ -1785,7 +1782,8 @@ void basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__invalidate_all(this); + if (!__libcpp_is_constant_evaluated()) + __get_db()->__invalidate_all(this); #endif } @@ -1795,22 +1793,24 @@ void basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) { #if _LIBCPP_DEBUG_LEVEL == 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - if (__c) - { - const_pointer __new_last = __get_pointer() + __pos; - for (__i_node** __p = __c->end_; __p != __c->beg_; ) + if (!__libcpp_is_constant_evaluated()) { + __c_node* __c = __get_db()->__find_c_and_lock(this); + if (__c) { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->base() > __new_last) + const_pointer __new_last = __get_pointer() + __pos; + for (__i_node** __p = __c->end_; __p != __c->beg_; ) { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + --__p; + const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); + if (__i->base() > __new_last) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } } + __get_db()->unlock(); } - __get_db()->unlock(); } #else (void)__pos; @@ -1823,9 +1823,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) : __r_(__default_init_tag(), __default_init_tag()) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1839,9 +1837,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #endif : __r_(__default_init_tag(), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1851,9 +1847,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __reserve) { if (__reserve > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__reserve < __min_cap) + if (__fits_in_sso(__reserve)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1875,9 +1871,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1901,9 +1897,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1913,9 +1907,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); __init(__s, __n); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1925,9 +1917,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1939,10 +1929,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1955,21 +1942,19 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { pointer __p; - if (__sz < __min_cap) { + if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); __set_short_size(__sz); } else { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); size_t __cap = __recommend(__sz); __p = __alloc_traits::allocate(__alloc(), __cap + 1); __set_long_pointer(__p); @@ -1992,9 +1977,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) : __r_(_VSTD::move(__str.__r_)) { __str.__zero(); + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - if (__is_long()) + if (!__libcpp_is_constant_evaluated() && __is_long()) __get_db()->swap(this, &__str); #endif } @@ -2011,9 +1996,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, co __r_.first().__r = __str.__r_.first().__r; __str.__zero(); } + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - if (__is_long()) + if (!__libcpp_is_constant_evaluated() && __is_long()) __get_db()->swap(this, &__str); #endif } @@ -2025,9 +2010,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { if (__n > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__n < __min_cap) + if (__fits_in_sso(__n)) { __set_short_size(__n); __p = __get_short_pointer(); @@ -2050,9 +2035,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2061,9 +2044,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __a) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2074,11 +2055,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2089,11 +2068,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, __str_sz - __pos); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2105,9 +2082,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2117,9 +2092,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2129,14 +2102,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _ { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> -_EnableIf +__enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value > @@ -2162,7 +2133,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template <class _ForwardIterator> -_EnableIf +__enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > @@ -2170,9 +2141,9 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For { size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -2211,9 +2182,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2224,9 +2193,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __a) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #ifndef _LIBCPP_CXX03_LANG @@ -2238,9 +2205,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2251,9 +2216,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #endif // _LIBCPP_CXX03_LANG @@ -2262,7 +2225,8 @@ template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>::~basic_string() { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__erase_c(this); + if (!__libcpp_is_constant_evaluated()) + __get_db()->__erase_c(this); #endif if (__is_long()) __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); @@ -2276,7 +2240,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) - this->__throw_length_error(); + __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2308,7 +2272,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap) - this->__throw_length_error(); + __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2358,14 +2322,12 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external( if (__cap >= __n) { value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::move(__p, __s, __n); - traits_type::assign(__p[__n], value_type()); - __set_size(__n); - __invalidate_iterators_past(__n); + return __null_terminate_at(__p, __n); } else { size_type __sz = size(); __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); + return *this; } - return *this; } template <class _CharT, class _Traits, class _Allocator> @@ -2373,7 +2335,7 @@ 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 (_LIBCPP_BUILTIN_CONSTANT_P(__n) && __n < __min_cap) + return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); } @@ -2390,10 +2352,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) } value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); - traits_type::assign(__p[__n], value_type()); - __set_size(__n); - __invalidate_iterators_past(__n); - return *this; + return __null_terminate_at(__p, __n); } template <class _CharT, class _Traits, class _Allocator> @@ -2491,7 +2450,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> -_EnableIf +__enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string<_CharT, _Traits, _Allocator>& @@ -2505,7 +2464,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> -_EnableIf +__enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string<_CharT, _Traits, _Allocator>& @@ -2525,7 +2484,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For __grow_by(__cap, __n - __cap, __sz, 0, __sz); } pointer __p = __get_pointer(); - for (; __first != __last; ++__first, ++__p) + for (; __first != __last; ++__p, (void) ++__first) traits_type::assign(*__p, *__first); traits_type::assign(*__p, value_type()); __set_size(__n); @@ -2545,13 +2504,13 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -2562,7 +2521,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2578,8 +2537,8 @@ basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); - return _LIBCPP_BUILTIN_CONSTANT_P(*__s) - ? (traits_type::length(__s) < __min_cap + return __builtin_constant_p(*__s) + ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) : __assign_external(__s, traits_type::length(__s))) : __assign_external(__s); @@ -2665,7 +2624,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) if (__sz == __cap) { __grow_by(__cap, 1, __sz, __sz, 0); - __is_short = !__is_long(); + __is_short = false; // the string is always long after __grow_by } pointer __p; if (__is_short) @@ -2684,7 +2643,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> -_EnableIf +__enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string<_CharT, _Traits, _Allocator>& @@ -2703,7 +2662,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( if (__cap - __sz < __n) __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer() + __sz; - for (; __first != __last; ++__p, ++__first) + for (; __first != __last; ++__p, (void) ++__first) traits_type::assign(*__p, *__first); traits_type::assign(*__p, value_type()); __set_size(__sz + __n); @@ -2731,13 +2690,13 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> - _EnableIf + __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, basic_string<_CharT, _Traits, _Allocator>& @@ -2747,7 +2706,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2768,7 +2727,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __cap = capacity(); if (__cap - __sz >= __n) { @@ -2799,7 +2758,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); if (__n) { size_type __cap = capacity(); @@ -2826,36 +2785,33 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> -_EnableIf +__enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, typename basic_string<_CharT, _Traits, _Allocator>::iterator > basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, - "string::insert(iterator, range) called with an iterator not" - " referring to this string"); -#endif - const basic_string __temp(__first, __last, __alloc()); - return insert(__pos, __temp.data(), __temp.data() + __temp.size()); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, range) called with an iterator not" + " referring to this string"); + const basic_string __temp(__first, __last, __alloc()); + return insert(__pos, __temp.data(), __temp.data() + __temp.size()); } template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> -_EnableIf +__enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, typename basic_string<_CharT, _Traits, _Allocator>::iterator > basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, - "string::insert(iterator, range) called with an iterator not" - " referring to this string"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, range) called with an iterator not" + " referring to this string"); + size_type __ip = static_cast<size_type>(__pos - begin()); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) @@ -2881,7 +2837,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward __sz += __n; __set_size(__sz); traits_type::assign(__p[__sz], value_type()); - for (__p += __ip; __first != __last; ++__p, ++__first) + for (__p += __ip; __first != __last; ++__p, (void) ++__first) traits_type::assign(*__p, *__first); } else @@ -2908,13 +2864,13 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, basic_string<_CharT, _Traits, _Allocator>& @@ -2925,7 +2881,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } @@ -2941,6 +2897,10 @@ template <class _CharT, class _Traits, class _Allocator> typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, character) called with an iterator not" + " referring to this string"); + size_type __ip = static_cast<size_type>(__pos - begin()); size_type __sz = size(); size_type __cap = capacity(); @@ -2968,14 +2928,12 @@ inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, - "string::insert(iterator, n, value) called with an iterator not" - " referring to this string"); -#endif - difference_type __p = __pos - begin(); - insert(static_cast<size_type>(__p), __n, __c); - return begin() + __p; + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::insert(iterator, n, value) called with an iterator not" + " referring to this string"); + difference_type __p = __pos - begin(); + insert(static_cast<size_type>(__p), __n, __c); + return begin() + __p; } // replace @@ -2988,7 +2946,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) @@ -3003,7 +2961,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ { traits_type::move(__p + __pos, __s, __n2); traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); - goto __finish; + return __null_terminate_at(__p, __sz + (__n2 - __n1)); } if (__p + __pos < __s && __s < __p + __sz) { @@ -3022,13 +2980,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } } 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()); + return __null_terminate_at(__p, __sz + (__n2 - __n1)); } else __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); @@ -3038,11 +2990,10 @@ __finish: template <class _CharT, class _Traits, class _Allocator> 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 { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); value_type* __p; @@ -3062,16 +3013,12 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ __p = _VSTD::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n2, __c); - __sz += __n2 - __n1; - __set_size(__sz); - __invalidate_iterators_past(__sz); - traits_type::assign(__p[__sz], value_type()); - return *this; + return __null_terminate_at(__p, __sz - (__n1 - __n2)); } template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> -_EnableIf +__enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, basic_string<_CharT, _Traits, _Allocator>& @@ -3080,7 +3027,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it _InputIterator __j1, _InputIterator __j2) { const basic_string __temp(__j1, __j2, __alloc()); - return this->replace(__i1, __i2, __temp); + return replace(__i1, __i2, __temp); } template <class _CharT, class _Traits, class _Allocator> @@ -3098,13 +3045,13 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, basic_string<_CharT, _Traits, _Allocator>& @@ -3115,7 +3062,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } @@ -3177,10 +3124,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( size_type __n_move = __sz - __pos - __n; if (__n_move != 0) traits_type::move(__p + __pos, __p + __pos + __n, __n_move); - __sz -= __n; - __set_size(__sz); - __invalidate_iterators_past(__sz); - traits_type::assign(__p[__sz], value_type()); + __null_terminate_at(__p, __sz - __n); } } @@ -3188,7 +3132,8 @@ template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { - if (__pos > size()) this->__throw_out_of_range(); + if (__pos > size()) + __throw_out_of_range(); if (__n == npos) { __erase_to_end(__pos); } else { @@ -3202,17 +3147,15 @@ inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, - "string::erase(iterator) called with an iterator not" - " referring to this string"); -#endif - _LIBCPP_ASSERT(__pos != end(), - "string::erase(iterator) called with a non-dereferenceable iterator"); - iterator __b = begin(); - size_type __r = static_cast<size_type>(__pos - __b); - erase(__r, 1); - return __b + static_cast<difference_type>(__r); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, + "string::erase(iterator) called with an iterator not" + " referring to this string"); + + _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); + iterator __b = begin(); + size_type __r = static_cast<size_type>(__pos - __b); + erase(__r, 1); + return __b + static_cast<difference_type>(__r); } template <class _CharT, class _Traits, class _Allocator> @@ -3220,16 +3163,15 @@ inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, - "string::erase(iterator, iterator) called with an iterator not" - " referring to this string"); -#endif - _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); - iterator __b = begin(); - size_type __r = static_cast<size_type>(__first - __b); - erase(__r, static_cast<size_type>(__last - __first)); - return __b + static_cast<difference_type>(__r); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + "string::erase(iterator, iterator) called with an iterator not" + " referring to this string"); + + _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); + iterator __b = begin(); + size_type __r = static_cast<size_type>(__first - __b); + erase(__r, static_cast<size_type>(__last - __first)); + return __b + static_cast<difference_type>(__r); } template <class _CharT, class _Traits, class _Allocator> @@ -3238,20 +3180,7 @@ void basic_string<_CharT, _Traits, _Allocator>::pop_back() { _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); - size_type __sz; - if (__is_long()) - { - __sz = __get_long_size() - 1; - __set_long_size(__sz); - traits_type::assign(*(__get_long_pointer() + __sz), value_type()); - } - else - { - __sz = __get_short_size() - 1; - __set_short_size(__sz); - traits_type::assign(*(__get_short_pointer() + __sz), value_type()); - } - __invalidate_iterators_past(__sz); + __erase_to_end(size() - 1); } template <class _CharT, class _Traits, class _Allocator> @@ -3277,17 +3206,7 @@ inline void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { - if (__is_long()) - { - traits_type::assign(*(__get_long_pointer() + __pos), value_type()); - __set_long_size(__pos); - } - else - { - traits_type::assign(*(__get_short_pointer() + __pos), value_type()); - __set_short_size(__pos); - } - __invalidate_iterators_past(__pos); + __null_terminate_at(_VSTD::__to_address(__get_pointer()), __pos); } template <class _CharT, class _Traits, class _Allocator> @@ -3330,12 +3249,13 @@ void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { if (__requested_capacity > max_size()) - this->__throw_length_error(); + __throw_length_error(); -#if _LIBCPP_STD_VER > 17 - // Reserve never shrinks as of C++20. - if (__requested_capacity <= capacity()) return; -#endif + // Make sure reserve(n) never shrinks. This is technically only required in C++20 + // and later (since P0966R1), however we provide consistent behavior in all Standard + // modes because this function is instantiated in the shared library. + if (__requested_capacity <= capacity()) + return; size_type __target_capacity = _VSTD::max(__requested_capacity, size()); __target_capacity = __recommend(__target_capacity); @@ -3345,6 +3265,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit } template <class _CharT, class _Traits, class _Allocator> +inline void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { @@ -3355,6 +3276,7 @@ basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> +inline void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { @@ -3434,7 +3356,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3443,7 +3365,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3489,7 +3411,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n, __sz - __pos); traits_type::copy(__s, data() + __pos, __rlen); return __rlen; @@ -3515,11 +3437,13 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #endif { #if _LIBCPP_DEBUG_LEVEL == 2 - if (!__is_long()) - __get_db()->__invalidate_all(this); - if (!__str.__is_long()) - __get_db()->__invalidate_all(&__str); - __get_db()->swap(this, &__str); + if (!__libcpp_is_constant_evaluated()) { + if (!__is_long()) + __get_db()->__invalidate_all(this); + if (!__str.__is_long()) + __get_db()->__invalidate_all(&__str); + __get_db()->swap(this, &__str); + } #endif _LIBCPP_ASSERT( __alloc_traits::propagate_on_container_swap::value || @@ -3563,7 +3487,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3621,7 +3545,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3679,7 +3603,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3737,7 +3661,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3795,7 +3719,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3854,7 +3778,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, typename basic_string<_CharT, _Traits, _Allocator>::size_type @@ -3892,7 +3816,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int @@ -3931,7 +3855,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); size_type __sz = size(); if (__pos1 > __sz || __n2 == npos) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n1, __sz - __pos1); int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); if (__r == 0) @@ -3946,7 +3870,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int @@ -3971,7 +3895,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> -_EnableIf +__enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -3995,7 +3919,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __pos2, size_type __n2) const { - return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); + return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } template <class _CharT, class _Traits, class _Allocator> @@ -4409,6 +4333,7 @@ _LIBCPP_FUNC_VIS string to_string(float __val); _LIBCPP_FUNC_VIS string to_string(double __val); _LIBCPP_FUNC_VIS string to_string(long double __val); +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS _LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); _LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); _LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); @@ -4428,6 +4353,7 @@ _LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); _LIBCPP_FUNC_VIS wstring to_wstring(float __val); _LIBCPP_FUNC_VIS wstring to_wstring(double __val); _LIBCPP_FUNC_VIS wstring to_wstring(long double __val); +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS template<class _CharT, class _Traits, class _Allocator> _LIBCPP_TEMPLATE_DATA_VIS @@ -4507,16 +4433,16 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return this->data() <= _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) < this->data() + this->size(); + return data() <= _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) < data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const { - return this->data() < _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) <= this->data() + this->size(); + return data() < _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4524,7 +4450,7 @@ bool basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const { const value_type* __p = _VSTD::__to_address(__i->base()) + __n; - return this->data() <= __p && __p <= this->data() + this->size(); + return data() <= __p && __p <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4532,7 +4458,7 @@ bool basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const { const value_type* __p = _VSTD::__to_address(__i->base()) + __n; - return this->data() <= __p && __p < this->data() + this->size(); + return data() <= __p && __p < data() + size(); } #endif // _LIBCPP_DEBUG_LEVEL == 2 @@ -4549,11 +4475,13 @@ inline namespace literals return basic_string<char> (__str, __len); } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) { return basic_string<wchar_t> (__str, __len); } +#endif #ifndef _LIBCPP_HAS_NO_CHAR8_T inline _LIBCPP_INLINE_VISIBILITY @@ -4574,8 +4502,8 @@ inline namespace literals { return basic_string<char32_t> (__str, __len); } - } -} + } // namespace string_literals +} // namespace literals #endif _LIBCPP_END_NAMESPACE_STD |
