diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -791,120 +791,268 @@ _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string() - _NOEXCEPT_(is_nothrow_default_constructible::value); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __r_(__default_init_tag(), __default_init_tag()) { + std::__debug_db_insert_c(this); + __default_init(); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 - _NOEXCEPT_(is_nothrow_copy_constructible::value); + _NOEXCEPT_(is_nothrow_copy_constructible::value) #else - _NOEXCEPT; + _NOEXCEPT #endif + : __r_(__default_init_tag(), __a) { + std::__debug_db_insert_c(this); + __default_init(); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str) + : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { + if (!__str.__is_long()) + __r_.first().__r = __str.__r_.first().__r; + else + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); + std::__debug_db_insert_c(this); + } - _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str); - _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + if (!__str.__is_long()) + __r_.first().__r = __str.__r_.first().__r; + else + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); + std::__debug_db_insert_c(this); + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(basic_string&& __str) -#if _LIBCPP_STD_VER <= 14 - _NOEXCEPT_(is_nothrow_move_constructible::value); -#else - _NOEXCEPT; -#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str) +# if _LIBCPP_STD_VER <= 14 + _NOEXCEPT_(is_nothrow_move_constructible::value) +# else + _NOEXCEPT +# endif + : __r_(std::move(__str.__r_)) { + __str.__default_init(); + std::__debug_db_insert_c(this); + if (__is_long()) + std::__debug_db_swap(this, &__str); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str, const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + if (__str.__is_long() && __a != __str.__alloc()) // copy, not move + __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); + else { + if (__libcpp_is_constant_evaluated()) { + __zero(); + __r_.first().__l = __str.__r_.first().__l; + } else { + __r_.first().__r = __str.__r_.first().__r; + } + __str.__default_init(); + } + std::__debug_db_insert_c(this); + if (__is_long()) + std::__debug_db_swap(this, &__str); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG - template ::value, nullptr_t> > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); - __init(__s, traits_type::length(__s)); - std::__debug_db_insert_c(this); - } + template ::value, nullptr_t> > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s) + : __r_(__default_init_tag(), __default_init_tag()) { + _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); + __init(__s, traits_type::length(__s)); + std::__debug_db_insert_c(this); + } - template ::value, nullptr_t> > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const _CharT* __s, const _Allocator& __a); + template ::value, nullptr_t> > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, const _Allocator& __a) + : __r_(__default_init_tag(), __a) { + _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); + __init(__s, traits_type::length(__s)); + std::__debug_db_insert_c(this); + } #if _LIBCPP_STD_VER > 20 - basic_string(nullptr_t) = delete; + basic_string(nullptr_t) = delete; #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const _CharT* __s, size_type __n); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(size_type __n, _CharT __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n) + : __r_(__default_init_tag(), __default_init_tag()) { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); + __init(__s, __n); + std::__debug_db_insert_c(this); + } - template ::value, nullptr_t> > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(size_type __n, _CharT __c, const _Allocator& __a); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a) + : __r_(__default_init_tag(), __a) { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); + __init(__s, __n); + std::__debug_db_insert_c(this); + } - _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const basic_string& __str, size_type __pos, size_type __n, - const _Allocator& __a = _Allocator()); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(const basic_string& __str, size_type __pos, - const _Allocator& __a = _Allocator()); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c) + : __r_(__default_init_tag(), __default_init_tag()) { + __init(__n, __c); + std::__debug_db_insert_c(this); + } + + template ::value, nullptr_t> > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c, const _Allocator& __a) + : __r_(__default_init_tag(), __a) { + __init(__n, __c); + std::__debug_db_insert_c(this); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()) + : __r_(__default_init_tag(), __a) { + size_type __str_sz = __str.size(); + if (__pos > __str_sz) + __throw_out_of_range(); + __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); + std::__debug_db_insert_c(this); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, + const _Allocator& __a = _Allocator()) + : __r_(__default_init_tag(), __a) { + size_type __str_sz = __str.size(); + if (__pos > __str_sz) + __throw_out_of_range(); + __init(__str.data() + __pos, __str_sz - __pos); + std::__debug_db_insert_c(this); + } - template::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _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_CONSTEXPR_AFTER_CXX17 + basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()) + : __r_(__default_init_tag(), __a) { + __self_view __sv0 = __t; + __self_view __sv = __sv0.substr(__pos, __n); + __init(__sv.data(), __sv.size()); + std::__debug_db_insert_c(this); + } - template::value && - !__is_same_uncvref<_Tp, basic_string>::value> > - _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_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t) + : __r_(__default_init_tag(), __default_init_tag()) { + __self_view __sv = __t; + __init(__sv.data(), __sv.size()); + std::__debug_db_insert_c(this); + } - template::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 - explicit basic_string(const _Tp& __t, const allocator_type& __a); + template ::value && + !__is_same_uncvref<_Tp, basic_string>::value> > + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t, const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + __self_view __sv = __t; + __init(__sv.data(), __sv.size()); + std::__debug_db_insert_c(this); + } + + template ::value> > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last) + : __r_(__default_init_tag(), __default_init_tag()) { + __init(__first, __last); + std::__debug_db_insert_c(this); + } + + template ::value> > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + __init(__first, __last); + std::__debug_db_insert_c(this); + } - template::value> > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(_InputIterator __first, _InputIterator __last); - template::value> > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(initializer_list<_CharT> __il); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string(initializer_list<_CharT> __il, const _Allocator& __a); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il) + : __r_(__default_init_tag(), __default_init_tag()) { + __init(__il.begin(), __il.end()); + std::__debug_db_insert_c(this); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il, const _Allocator& __a) + : __r_(__default_init_tag(), __a) { + __init(__il.begin(), __il.end()); + std::__debug_db_insert_c(this); + } #endif // _LIBCPP_CXX03_LANG - inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string(); + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string() { + std::__debug_db_erase_c(this); + if (__is_long()) + __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); + } _LIBCPP_HIDE_FROM_ABI _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); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str) { + if (this != &__str) { + __copy_assign_alloc(__str); + if (!__is_long()) { + if (!__str.__is_long()) { + __r_.first().__r = __str.__r_.first().__r; + } else { + return __assign_no_alias(__str.data(), __str.size()); + } + } else { + return __assign_no_alias(__str.data(), __str.size()); + } } + return *this; + } + + template < + class _Tp, + class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && + !__is_same_uncvref<_Tp, basic_string>::value> > + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) { + __self_view __sv = __t; + return assign(__sv); + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& operator=(basic_string&& __str) - _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& operator=(initializer_list __il) {return assign(__il.begin(), __il.size());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& + operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) { + __move_assign(__str, integral_constant()); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(initializer_list __il) { + return assign(__il.begin(), __il.size()); + } #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& operator=(const value_type* __s) {return assign(__s);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const value_type* __s) { + return assign(__s); + } #if _LIBCPP_STD_VER > 20 - basic_string& operator=(nullptr_t) = delete; + basic_string& operator=(nullptr_t) = delete; #endif - _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c) { + pointer __p; + if (__is_long()) { + __p = __get_long_pointer(); + __set_long_size(1); + } else { + __p = __get_short_pointer(); + __set_short_size(1); + } + traits_type::assign(*__p, __c); + traits_type::assign(*++__p, value_type()); + __invalidate_iterators_past(1); + return *this; + } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT @@ -1077,54 +1225,111 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT; - template - _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_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& assign(const basic_string& __str) { return *this = __str; } + template + _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_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str) { + return *this = __str; + } + #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& assign(basic_string&& __str) - _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) - {*this = std::move(__str); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& + assign(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) { + *this = std::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_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& - > - 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_CONSTEXPR_AFTER_CXX17 - __enable_if_t - < - __is_exactly_cpp17_input_iterator<_InputIterator>::value, - basic_string& - > - assign(_InputIterator __first, _InputIterator __last); - template - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 - __enable_if_t - < - __is_cpp17_forward_iterator<_ForwardIterator>::value, - basic_string& - > - assign(_ForwardIterator __first, _ForwardIterator __last); + + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos) { + size_type __sz = __str.size(); + if (__pos > __sz) + __throw_out_of_range(); + return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); + } + + template + _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&> + assign(const _Tp& __t, size_type __pos, size_type __n = npos) { + __self_view __sv = __t; + size_type __sz = __sv.size(); + if (__pos > __sz) + __throw_out_of_range(); + return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s, size_type __n) { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); + return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s) { + _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); + 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); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(size_type __n, value_type __c) { + size_type __cap = capacity(); + if (__cap < __n) { + size_type __sz = size(); + __grow_by(__cap, __n - __cap, __sz, 0, __sz); + } + value_type* __p = std::__to_address(__get_pointer()); + traits_type::assign(__p, __n, __c); + return __null_terminate_at(__p, __n); + } + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 + __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string&> + assign(_InputIterator __first, _InputIterator __last) { + const basic_string __temp(__first, __last, __alloc()); + assign(__temp.data(), __temp.size()); + return *this; + } + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 + __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string&> + assign(_ForwardIterator __first, _ForwardIterator __last) { + size_type __cap = capacity(); + size_type __n = + __string_is_trivial_iterator<_ForwardIterator>::value + ? static_cast(std::distance(__first, __last)) + : 0; + + if (__string_is_trivial_iterator<_ForwardIterator>::value && (__cap >= __n || !__addr_in_range(*__first))) { + if (__cap < __n) { + size_type __sz = size(); + __grow_by(__cap, __n - __cap, __sz, 0, __sz); + } + pointer __p = __get_pointer(); + for (; __first != __last; ++__p, (void)++__first) + traits_type::assign(*__p, *__first); + traits_type::assign(*__p, value_type()); + __set_size(__n); + __invalidate_iterators_past(__n); + } else { + const basic_string __temp(__first, __last, __alloc()); + assign(__temp.data(), __temp.size()); + } + return *this; + } + #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 - basic_string& assign(initializer_list __il) {return assign(__il.begin(), __il.size());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(initializer_list __il) { + return assign(__il.begin(), __il.size()); + } #endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -1873,30 +2078,6 @@ #endif // _LIBCPP_ENABLE_DEBUG_MODE } -template -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()) -{ - std::__debug_db_insert_c(this); - __default_init(); -} - -template -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) -#else - _NOEXCEPT -#endif -: __r_(__default_init_tag(), __a) -{ - std::__debug_db_insert_c(this); - __default_init(); -} - template _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, @@ -1954,64 +2135,6 @@ traits_type::assign(__p[__sz], value_type()); } -template -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); - __init(__s, traits_type::length(__s)); - std::__debug_db_insert_c(this); -} - -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) - : __r_(__default_init_tag(), __default_init_tag()) -{ - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); - __init(__s, __n); - std::__debug_db_insert_c(this); -} - -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); - __init(__s, __n); - std::__debug_db_insert_c(this); -} - -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())) -{ - if (!__str.__is_long()) - __r_.first().__r = __str.__r_.first().__r; - else - __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), - __str.__get_long_size()); - std::__debug_db_insert_c(this); -} - -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) -{ - if (!__str.__is_long()) - __r_.first().__r = __str.__r_.first().__r; - else - __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), - __str.__get_long_size()); - std::__debug_db_insert_c(this); -} - template _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( @@ -2035,48 +2158,6 @@ traits_type::copy(std::__to_address(__p), __s, __sz + 1); } -#ifndef _LIBCPP_CXX03_LANG - -template -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) -#else - _NOEXCEPT -#endif - : __r_(std::move(__str.__r_)) -{ - __str.__default_init(); - std::__debug_db_insert_c(this); - if (__is_long()) - std::__debug_db_swap(this, &__str); -} - -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) - : __r_(__default_init_tag(), __a) -{ - if (__str.__is_long() && __a != __str.__alloc()) // copy, not move - __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - else - { - if (__libcpp_is_constant_evaluated()) { - __zero(); - __r_.first().__l = __str.__r_.first().__l; - } else { - __r_.first().__r = __str.__r_.first().__r; - } - __str.__default_init(); - } - std::__debug_db_insert_c(this); - if (__is_long()) - std::__debug_db_swap(this, &__str); -} - -#endif // _LIBCPP_CXX03_LANG - template _LIBCPP_CONSTEXPR_AFTER_CXX17 void @@ -2105,87 +2186,6 @@ traits_type::assign(__p[__n], value_type()); } -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) - : __r_(__default_init_tag(), __default_init_tag()) -{ - __init(__n, __c); - std::__debug_db_insert_c(this); -} - -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) -{ - __init(__n, __c); - std::__debug_db_insert_c(this); -} - -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) - : __r_(__default_init_tag(), __a) -{ - size_type __str_sz = __str.size(); - if (__pos > __str_sz) - __throw_out_of_range(); - __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); - std::__debug_db_insert_c(this); -} - -template -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) -{ - size_type __str_sz = __str.size(); - if (__pos > __str_sz) - __throw_out_of_range(); - __init(__str.data() + __pos, __str_sz - __pos); - std::__debug_db_insert_c(this); -} - -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) -{ - __self_view __sv0 = __t; - __self_view __sv = __sv0.substr(__pos, __n); - __init(__sv.data(), __sv.size()); - std::__debug_db_insert_c(this); -} - -template -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) - : __r_(__default_init_tag(), __default_init_tag()) -{ - __self_view __sv = __t; - __init(__sv.data(), __sv.size()); - std::__debug_db_insert_c(this); -} - -template -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - __self_view __sv = __t; - __init(__sv.data(), __sv.size()); - std::__debug_db_insert_c(this); -} - template template _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -2261,60 +2261,6 @@ #endif // _LIBCPP_NO_EXCEPTIONS } -template -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) - : __r_(__default_init_tag(), __default_init_tag()) -{ - __init(__first, __last); - std::__debug_db_insert_c(this); -} - -template -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, - const allocator_type& __a) - : __r_(__default_init_tag(), __a) -{ - __init(__first, __last); - std::__debug_db_insert_c(this); -} - -#ifndef _LIBCPP_CXX03_LANG - -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string( - initializer_list<_CharT> __il) - : __r_(__default_init_tag(), __default_init_tag()) -{ - __init(__il.begin(), __il.end()); - std::__debug_db_insert_c(this); -} - -template -inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::basic_string( - initializer_list<_CharT> __il, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - __init(__il.begin(), __il.end()); - std::__debug_db_insert_c(this); -} - -#endif // _LIBCPP_CXX03_LANG - -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>::~basic_string() -{ - std::__debug_db_erase_c(this); - if (__is_long()) - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); -} - template _LIBCPP_CONSTEXPR_AFTER_CXX17 void @@ -2421,75 +2367,6 @@ } } -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) && __fits_in_sso(__n)) - ? __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) -{ - size_type __cap = capacity(); - if (__cap < __n) - { - size_type __sz = size(); - __grow_by(__cap, __n - __cap, __sz, 0, __sz); - } - value_type* __p = std::__to_address(__get_pointer()); - traits_type::assign(__p, __n, __c); - return __null_terminate_at(__p, __n); -} - -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>& -basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) -{ - pointer __p; - if (__is_long()) - { - __p = __get_long_pointer(); - __set_long_size(1); - } - else - { - __p = __get_short_pointer(); - __set_short_size(1); - } - traits_type::assign(*__p, __c); - traits_type::assign(*++__p, value_type()); - __invalidate_iterators_past(1); - return *this; -} - -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -basic_string<_CharT, _Traits, _Allocator>& -basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) -{ - if (this != &__str) { - __copy_assign_alloc(__str); - if (!__is_long()) { - if (!__str.__is_long()) { - __r_.first().__r = __str.__r_.first().__r; - } else { - return __assign_no_alias(__str.data(), __str.size()); - } - } else { - return __assign_no_alias(__str.data(), __str.size()); - } - } - return *this; -} - #ifndef _LIBCPP_CXX03_LANG template @@ -2534,101 +2411,8 @@ } } -template -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)) -{ - __move_assign(__str, integral_constant()); - return *this; -} - #endif -template -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -__enable_if_t -< - __is_exactly_cpp17_input_iterator<_InputIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& -> -basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) -{ - const basic_string __temp(__first, __last, __alloc()); - assign(__temp.data(), __temp.size()); - return *this; -} - -template -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 -__enable_if_t -< - __is_cpp17_forward_iterator<_ForwardIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& -> -basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) -{ - size_type __cap = capacity(); - size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? - static_cast(std::distance(__first, __last)) : 0; - - if (__string_is_trivial_iterator<_ForwardIterator>::value && - (__cap >= __n || !__addr_in_range(*__first))) - { - if (__cap < __n) - { - size_type __sz = size(); - __grow_by(__cap, __n - __cap, __sz, 0, __sz); - } - pointer __p = __get_pointer(); - for (; __first != __last; ++__p, (void) ++__first) - traits_type::assign(*__p, *__first); - traits_type::assign(*__p, value_type()); - __set_size(__n); - __invalidate_iterators_past(__n); - } - else - { - const basic_string __temp(__first, __last, __alloc()); - assign(__temp.data(), __temp.size()); - } - return *this; -} - -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) -{ - size_type __sz = __str.size(); - if (__pos > __sz) - __throw_out_of_range(); - return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); -} - -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, - basic_string<_CharT, _Traits, _Allocator>& -> -basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) -{ - __self_view __sv = __t; - size_type __sz = __sv.size(); - if (__pos > __sz) - __throw_out_of_range(); - return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); -} - - template _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& @@ -2636,18 +2420,6 @@ return __assign_external(__s, traits_type::length(__s)); } -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) - ? (__fits_in_sso(traits_type::length(__s)) - ? __assign_short(__s, traits_type::length(__s)) - : __assign_external(__s, traits_type::length(__s))) - : __assign_external(__s); -} // append template