[libc++] Remove the usage of __init in operator+
`operator+` currently calls `__init`. This patch removes the usage of implementation details.
Reviewed By: ldionne, Mordante, #libc
Spies: libcxx-commits
Differential Revision: https://reviews.llvm.org/D123058
NOKEYCHECK=True
GitOrigin-RevId: 732920d847e5da8942da7eb48f65507951f5da60
diff --git a/include/string b/include/string
index daa6a68..9fd19d2 100644
--- a/include/string
+++ b/include/string
@@ -625,6 +625,8 @@
typedef basic_string<char32_t> u32string;
#endif
+struct __uninitialized_size_tag {};
+
template<class _CharT, class _Traits, class _Allocator>
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;
}