[libcxx-commits] [libcxx] 8fcb60a - [libc++][NFC] Introduce __data() to std::string to replace std::__to_address(__get_pointer()) (#178212)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 4 01:19:44 PST 2026


Author: Nikolas Klauser
Date: 2026-03-04T10:19:34+01:00
New Revision: 8fcb60aa47e792641dcbe6dcaa8b4a822a565cfc

URL: https://github.com/llvm/llvm-project/commit/8fcb60aa47e792641dcbe6dcaa8b4a822a565cfc
DIFF: https://github.com/llvm/llvm-project/commit/8fcb60aa47e792641dcbe6dcaa8b4a822a565cfc.diff

LOG: [libc++][NFC] Introduce __data() to std::string to replace std::__to_address(__get_pointer()) (#178212)

`std::__to_address(__get_pointer())` is an extremely common pattern
inside `string` and is basically equivalent to `data()`, except that
`data()` only returns a non-const pointer since C++17. This patch
introduces `__data()` to back-port returning a non-const pointer.

Added: 
    

Modified: 
    libcxx/include/string

Removed: 
    


################################################################################
diff  --git a/libcxx/include/string b/libcxx/include/string
index c4bf970e55004..37f00c2d189df 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1456,7 +1456,7 @@ public:
       if (__cap - __sz < __n)
         __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
       __annotate_increase(__n);
-      auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
+      auto __end = __copy_non_overlapping_range(__first, __last, __data() + __sz);
       traits_type::assign(*__end, value_type());
       __set_size(__sz + __n);
       return *this;
@@ -1813,6 +1813,13 @@ public:
   }
 #  endif
 
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* __data() const _NOEXCEPT {
+    return std::__to_address(__get_pointer());
+  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* __data() _NOEXCEPT {
+    return std::__to_address(__get_pointer());
+  }
+
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
     return __alloc_;
   }
@@ -2171,7 +2178,7 @@ private:
     value_type* __p;
     if (__cap - __sz >= __n) {
       __annotate_increase(__n);
-      __p                = std::__to_address(__get_pointer());
+      __p                = __data();
       size_type __n_move = __sz - __ip;
       if (__n_move != 0)
         traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
@@ -2456,7 +2463,7 @@ private:
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
     _LIBCPP_ASSERT_INTERNAL(__pos <= capacity(), "Trying to erase at position outside the strings capacity!");
-    __null_terminate_at(std::__to_address(__get_pointer()), __pos);
+    __null_terminate_at(__data(), __pos);
   }
 
   // __erase_external_with_move is invoked for erase() invocations where
@@ -2726,19 +2733,18 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
     size_type __n_del,
     size_type __n_add,
     const value_type* __p_new_stuff) {
-  __long __buffer = __allocate_long_buffer(__alloc_, 0, __get_amortized_growth_capacity(__old_cap + __delta_cap));
-  pointer __old_p = __get_pointer();
+  __long __buffer     = __allocate_long_buffer(__alloc_, 0, __get_amortized_growth_capacity(__old_cap + __delta_cap));
+  value_type* __old_p = __data();
   __annotate_delete();
   auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
   if (__n_copy != 0)
-    traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
+    traits_type::copy(std::__to_address(__buffer.__data_), __old_p, __n_copy);
   if (__n_add != 0)
     traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy, __p_new_stuff, __n_add);
   size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
   if (__sec_cp_sz != 0)
-    traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy + __n_add,
-                      std::__to_address(__old_p) + __n_copy + __n_del,
-                      __sec_cp_sz);
+    traits_type::copy(
+        std::__to_address(__buffer.__data_) + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
   __buffer.__size_ = __n_copy + __n_add + __sec_cp_sz;
   traits_type::assign(__buffer.__data_[__buffer.__size_], value_type());
   __reset_internal_buffer(__buffer);
@@ -2759,15 +2765,14 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
     size_type __n_copy,
     size_type __n_del,
     size_type __n_add) {
-  __long __buffer = __allocate_long_buffer(__alloc_, 0, __get_amortized_growth_capacity(__old_cap + __delta_cap));
-  pointer __old_p = __get_pointer();
+  __long __buffer     = __allocate_long_buffer(__alloc_, 0, __get_amortized_growth_capacity(__old_cap + __delta_cap));
+  value_type* __old_p = __data();
   if (__n_copy != 0)
-    traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
+    traits_type::copy(std::__to_address(__buffer.__data_), __old_p, __n_copy);
   size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
   if (__sec_cp_sz != 0)
-    traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy + __n_add,
-                      std::__to_address(__old_p) + __n_copy + __n_del,
-                      __sec_cp_sz);
+    traits_type::copy(
+        std::__to_address(__buffer.__data_) + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
   // This is -1 to make sure the caller sets the size properly, since old versions of this function didn't set the size
   // at all.
   __buffer.__size_ = -1;
@@ -2828,7 +2833,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* _
   if (__cap >= __n) {
     if (__n > __size)
       __annotate_increase(__n - __size);
-    value_type* __p = std::__to_address(__get_pointer());
+    value_type* __p = __data();
     traits_type::move(__p, __s, __n);
     return __null_terminate_at(__p, __n);
   } else {
@@ -2854,7 +2859,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
     __annotate_increase(__n);
   } else if (__n > __old_size)
     __annotate_increase(__n - __old_size);
-  value_type* __p = std::__to_address(__get_pointer());
+  value_type* __p = __data();
   traits_type::assign(__p, __n, __c);
   return __null_terminate_at(__p, __n);
 }
@@ -3039,7 +3044,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
     return *this;
 
   __annotate_increase(__n);
-  value_type* __p = std::__to_address(__get_pointer());
+  value_type* __p = __data();
   traits_type::copy(__p + __sz, __s, __n);
   __sz += __n;
   __set_size(__sz);
@@ -3058,7 +3063,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
   if (__cap - __sz < __n)
     __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
   __annotate_increase(__n);
-  pointer __p = __get_pointer();
+  value_type* __p = __data();
   traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
   __sz += __n;
   __set_size(__sz);
@@ -3131,7 +3136,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
     return *this;
 
   __annotate_increase(__n);
-  value_type* __p    = std::__to_address(__get_pointer());
+  value_type* __p    = __data();
   size_type __n_move = __sz - __pos;
   if (__n_move != 0) {
     if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))
@@ -3159,7 +3164,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
   value_type* __p;
   if (__cap - __sz >= __n) {
     __annotate_increase(__n);
-    __p                = std::__to_address(__get_pointer());
+    __p                = __data();
     size_type __n_move = __sz - __pos;
     if (__n_move != 0)
       traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
@@ -3220,7 +3225,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
     __p = std::__to_address(__get_long_pointer());
   } else {
     __annotate_increase(1);
-    __p                = std::__to_address(__get_pointer());
+    __p                = __data();
     size_type __n_move = __sz - __ip;
     if (__n_move != 0)
       traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
@@ -3249,7 +3254,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
     return *this;
   }
 
-  value_type* __p = std::__to_address(__get_pointer());
+  value_type* __p = __data();
   if (__n1 != __n2) {
     if (__n2 > __n1)
       __annotate_increase(__n2 - __n1);
@@ -3288,7 +3293,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
   size_type __cap = capacity();
   value_type* __p;
   if (__cap - __sz + __n1 >= __n2) {
-    __p = std::__to_address(__get_pointer());
+    __p = __data();
     if (__n1 != __n2) {
       if (__n2 > __n1)
         __annotate_increase(__n2 - __n1);
@@ -3332,7 +3337,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type
     return;
 
   size_type __sz     = size();
-  value_type* __p    = std::__to_address(__get_pointer());
+  value_type* __p    = __data();
   __n                = std::min(__n, __sz - __pos);
   size_type __n_move = __sz - __pos - __n;
   if (__n_move != 0)
@@ -3713,7 +3718,7 @@ __concatenate_strings(const _Allocator& __alloc,
   _String __r(__uninitialized_size_tag(),
               __str1.size() + __str2.size(),
               _String::__alloc_traits::select_on_container_copy_construction(__alloc));
-  auto __ptr = std::__to_address(__r.__get_pointer());
+  auto __ptr = __r.__data();
   _Traits::copy(__ptr, __str1.data(), __str1.size());
   _Traits::copy(__ptr + __str1.size(), __str2.data(), __str2.size());
   _Traits::assign(__ptr[__str1.size() + __str2.size()], _CharT());


        


More information about the libcxx-commits mailing list