-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][strings] P2591R5: Concatenation of strings and string views #88389
Changes from 32 commits
2d606f4
af56ab9
474d5b9
38f6e85
ea270b6
292cd8f
f312052
9a86ea1
695b4b6
2df55a5
6b77e5a
92d08d6
694e6fd
be56164
20b9120
a8c28fb
16fcbba
bdbaf38
5d804f5
6e4d6b4
9f27ece
43c78be
d56da5f
f4f26df
da99993
907bcc4
a7bf9a0
13d58fe
d214ef1
20f39e1
666cb62
e5e808f
d799472
0820ad9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -407,6 +407,24 @@ template<class charT, class traits, class Allocator> | |
basic_string<charT, traits, Allocator> | ||
operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20 | ||
|
||
template<class charT, class traits, class Allocator> | ||
constexpr basic_string<charT, traits, Allocator> | ||
operator+(const basic_string<charT, traits, Allocator>& lhs, | ||
type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 | ||
template<class charT, class traits, class Allocator> | ||
constexpr basic_string<charT, traits, Allocator> | ||
operator+(basic_string<charT, traits, Allocator>&& lhs, | ||
type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 | ||
template<class charT, class traits, class Allocator> | ||
constexpr basic_string<charT, traits, Allocator> | ||
operator+(type_identity_t<basic_string_view<charT, traits>> lhs, | ||
const basic_string<charT, traits, Allocator>& rhs); // Since C++26 | ||
template<class charT, class traits, class Allocator> | ||
constexpr basic_string<charT, traits, Allocator> | ||
operator+(type_identity_t<basic_string_view<charT, traits>> lhs, | ||
basic_string<charT, traits, Allocator>&& rhs); // Since C++26 | ||
|
||
|
||
template<class charT, class traits, class Allocator> | ||
bool operator==(const basic_string<charT, traits, Allocator>& lhs, | ||
const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 | ||
|
@@ -687,6 +705,20 @@ 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+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, | ||
const 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&); | ||
|
||
|
@@ -2150,6 +2182,10 @@ private: | |
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 | ||
}; | ||
|
||
// These declarations must appear before any functions are implicitly used | ||
|
@@ -4007,6 +4043,60 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { | |
|
||
#endif // _LIBCPP_CXX03_LANG | ||
|
||
#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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure whether it would be better to drop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the review. I reverted my interpretations to the original wording in the paper, so I'll keep this as is for now as I understand it this is our practice and also the older implementations uses the same style. |
||
} | ||
|
||
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; | ||
} | ||
|
||
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); | ||
} | ||
|
||
#endif // _LIBCPP_STD_VER >= 26 | ||
|
||
// swap | ||
|
||
template <class _CharT, class _Traits, class _Allocator> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you forward declare all 4 new operators for consistency.