diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -625,6 +625,8 @@ typedef basic_string u32string; #endif +struct __uninitialized_size_tag {}; + template class _LIBCPP_TEMPLATE_VIS @@ -746,6 +748,26 @@ __compressed_pair<__rep, allocator_type> __r_; + // Construct a string with the given allocator and enough storage to hold `__size` characters, but + // don't initialize the characters. The contents of the string, including the null terminator, must be + // initialized separately. + _LIBCPP_HIDE_FROM_ABI explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) + : __r_(__default_init_tag(), __a) { + if (__size > max_size()) + __throw_length_error(); + if (__fits_in_sso(__size)) { + __zero(); + __set_short_size(__size); + } else { + auto __capacity = __recommend(__size) + 1; + auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); + __set_long_cap(__capacity); + __set_long_pointer(__allocation); + __set_long_size(__size); + } + std::__debug_db_insert_c(this); + } + public: _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; @@ -4156,11 +4178,15 @@ const basic_string<_CharT, _Traits, _Allocator>& __rhs) { using _String = basic_string<_CharT, _Traits, _Allocator>; - _String __r(_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); - typename _String::size_type __lhs_sz = __lhs.size(); - typename _String::size_type __rhs_sz = __rhs.size(); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + auto __lhs_sz = __lhs.size(); + auto __rhs_sz = __rhs.size(); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } @@ -4169,11 +4195,15 @@ operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) { using _String = basic_string<_CharT, _Traits, _Allocator>; - _String __r(_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); - typename _String::size_type __lhs_sz = _Traits::length(__lhs); - typename _String::size_type __rhs_sz = __rhs.size(); - __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + auto __lhs_sz = _Traits::length(__lhs); + auto __rhs_sz = __rhs.size(); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs, __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } @@ -4182,10 +4212,14 @@ operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) { using _String = basic_string<_CharT, _Traits, _Allocator>; - _String __r(_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); typename _String::size_type __rhs_sz = __rhs.size(); - __r.__init(&__lhs, 1, 1 + __rhs_sz); - __r.append(__rhs.data(), __rhs_sz); + _String __r(__uninitialized_size_tag(), + __rhs_sz + 1, + _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::assign(__ptr, 1, __lhs); + _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); + _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); return __r; } @@ -4195,11 +4229,15 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { using _String = basic_string<_CharT, _Traits, _Allocator>; - _String __r(_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); typename _String::size_type __lhs_sz = __lhs.size(); typename _String::size_type __rhs_sz = _Traits::length(__rhs); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); - __r.append(__rhs, __rhs_sz); + _String __r(__uninitialized_size_tag(), + __lhs_sz + __rhs_sz, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); + _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); return __r; } @@ -4208,10 +4246,14 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { using _String = basic_string<_CharT, _Traits, _Allocator>; - _String __r(_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); typename _String::size_type __lhs_sz = __lhs.size(); - __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1); - __r.push_back(__rhs); + _String __r(__uninitialized_size_tag(), + __lhs_sz + 1, + _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); + auto __ptr = std::__to_address(__r.__get_pointer()); + _Traits::copy(__ptr, __lhs.data(), __lhs_sz); + _Traits::assign(__ptr + __lhs_sz, 1, __rhs); + _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); return __r; }