[libcxx-commits] [libcxx] [libc++][NFC] Introduce __data() to std::string to replace std::__to_address(__get_pointer()) (PR #178212)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 27 06:34:44 PST 2026
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/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.
>From d107be38a011900fbe57ac35b89583ab8a9b9c1b Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 27 Jan 2026 15:33:07 +0100
Subject: [PATCH] [libc++][NFC] Introduce __data() to std::string to replace
std::__to_address(__get_pointer())
---
libcxx/include/string | 57 +++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 26 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index b7c7a5a1462b5..b83548ccdf8bb 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1450,7 +1450,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;
@@ -1807,6 +1807,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_;
}
@@ -2165,7 +2172,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);
@@ -2450,7 +2457,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
@@ -2720,19 +2727,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);
@@ -2753,15 +2759,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;
@@ -2822,7 +2827,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 {
@@ -2848,7 +2853,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);
}
@@ -3033,7 +3038,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);
@@ -3052,7 +3057,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);
@@ -3125,7 +3130,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))
@@ -3153,7 +3158,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);
@@ -3214,7 +3219,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);
@@ -3243,7 +3248,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);
@@ -3282,7 +3287,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);
@@ -3326,7 +3331,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)
@@ -3707,7 +3712,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 = __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