[libcxx-commits] [libcxx] [libc++] Avoid code duplication in strings operator+ overloads (PR #126048)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Feb 6 03:13:47 PST 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/126048
None
>From 31e57fcf1df331b282390b7fe8f3343b021066a9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 6 Feb 2025 11:38:41 +0100
Subject: [PATCH] [libc++] Avoid code duplication in strings operator+
overloads
---
libcxx/include/string | 188 +++++++++++-------------------------------
1 file changed, 48 insertions(+), 140 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index b7f2d122694639..4b749e47058a0d 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -691,50 +691,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// basic_string
-template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
-operator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
-operator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
-
-template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
-
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
-
-# if _LIBCPP_STD_VER >= 26
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
- type_identity_t<basic_string_view<_CharT, _Traits>> __rhs);
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, type_identity_t<basic_string_view<_CharT, _Traits>> __rhs);
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
- const basic_string<_CharT, _Traits, _Allocator>& __rhs);
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs);
-
-# endif
-
-extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
- <char, char_traits<char>, allocator<char> >(char const*, string const&);
+__concatenate_strings(const _Allocator& __alloc,
+ __type_identity_t<basic_string_view<_CharT, _Traits> > __str1,
+ __type_identity_t<basic_string_view<_CharT, _Traits> > __str2);
template <class _Iter>
struct __string_is_trivial_iterator : public false_type {};
@@ -2278,15 +2239,8 @@ private:
std::__throw_out_of_range("basic_string");
}
- friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&);
- friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&);
- friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&);
- friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*);
- friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type);
-# if _LIBCPP_STD_VER >= 26
- friend constexpr basic_string operator+ <>(const basic_string&, type_identity_t<__self_view>);
- friend constexpr basic_string operator+ <>(type_identity_t<__self_view>, const basic_string&);
-# endif
+ friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
+ __concatenate_strings<>(const _Allocator&, __type_identity_t<__self_view>, __type_identity_t<__self_view>);
template <class _CharT2, class _Traits2, class _Allocator2>
friend inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
@@ -3986,83 +3940,73 @@ operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>&
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
- const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
+__concatenate_strings(const _Allocator& __alloc,
+ __type_identity_t<basic_string_view<_CharT, _Traits> > __str1,
+ __type_identity_t<basic_string_view<_CharT, _Traits> > __str2) {
using _String = basic_string<_CharT, _Traits, _Allocator>;
- 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()));
+ __str1.size() + __str2.size(),
+ _String::__alloc_traits::select_on_container_copy_construction(__alloc));
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());
+ _Traits::copy(__ptr, __str1.data(), __str1.size());
+ _Traits::copy(__ptr + __str1.size(), __str2.data(), __str2.size());
+ _Traits::assign(__ptr[__str1.size() + __str2.size()], _CharT());
return __r;
}
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+ const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
+ return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
+}
+
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- 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;
+ return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
}
+extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
+ <char, char_traits<char>, allocator<char> >(char const*, string const&);
+
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- typename _String::size_type __rhs_sz = __rhs.size();
- _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;
+ return std::__concatenate_strings<_CharT, _Traits>(
+ __rhs.get_allocator(), basic_string_view<_CharT, _Traits>(&__lhs, 1), __rhs);
}
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- typename _String::size_type __lhs_sz = __lhs.size();
- typename _String::size_type __rhs_sz = _Traits::length(__rhs);
- _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;
+ return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- typename _String::size_type __lhs_sz = __lhs.size();
- _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;
+ return std::__concatenate_strings<_CharT, _Traits>(
+ __lhs.get_allocator(), __lhs, basic_string_view<_CharT, _Traits>(&__rhs, 1));
+}
+# if _LIBCPP_STD_VER >= 26
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+ type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
+ return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
+operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
+ const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
+ return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
}
+# endif // _LIBCPP_STD_VER >= 26
+
# ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
@@ -4113,54 +4057,18 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) {
# if _LIBCPP_STD_VER >= 26
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
- type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- typename _String::size_type __lhs_sz = __lhs.size();
- typename _String::size_type __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;
-}
-
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs,
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
- __lhs.append(__rhs);
- return std::move(__lhs);
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
-operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
- const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
- using _String = basic_string<_CharT, _Traits, _Allocator>;
- typename _String::size_type __lhs_sz = __lhs.size();
- typename _String::size_type __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.data(), __lhs_sz);
- _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
- _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
- return __r;
+ return std::move(__lhs.append(__rhs));
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
basic_string<_CharT, _Traits, _Allocator>&& __rhs) {
- __rhs.insert(0, __lhs);
- return std::move(__rhs);
+ return std::move(__rhs.insert(0, __lhs));
}
# endif // _LIBCPP_STD_VER >= 26
More information about the libcxx-commits
mailing list