[libcxx-commits] [libcxx] 732920d - [libc++] Remove the usage of __init in operator+

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Apr 11 07:00:13 PDT 2022


Author: Nikolas Klauser
Date: 2022-04-11T15:59:52+02:00
New Revision: 732920d847e5da8942da7eb48f65507951f5da60

URL: https://github.com/llvm/llvm-project/commit/732920d847e5da8942da7eb48f65507951f5da60
DIFF: https://github.com/llvm/llvm-project/commit/732920d847e5da8942da7eb48f65507951f5da60.diff

LOG: [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

Added: 
    

Modified: 
    libcxx/include/string

Removed: 
    


################################################################################
diff  --git a/libcxx/include/string b/libcxx/include/string
index daa6a68b230cb..9fd19d2ad9570 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -625,6 +625,8 @@ typedef basic_string<char16_t> u16string;
 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 @@ private:
 
     __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 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __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(__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 @@ basic_string<_CharT, _Traits, _Allocator>
 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 @@ basic_string<_CharT, _Traits, _Allocator>
 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 @@ basic_string<_CharT, _Traits, _Allocator>
 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 @@ basic_string<_CharT, _Traits, _Allocator>
 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;
 }
 


        


More information about the libcxx-commits mailing list