Skip to content

Commit 31e57fc

Browse files
committed
[libc++] Avoid code duplication in strings operator+ overloads
1 parent 4562efc commit 31e57fc

File tree

1 file changed

+48
-140
lines changed

1 file changed

+48
-140
lines changed

libcxx/include/string

Lines changed: 48 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -691,50 +691,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
691691

692692
// basic_string
693693

694-
template <class _CharT, class _Traits, class _Allocator>
695-
basic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
696-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
697-
698-
template <class _CharT, class _Traits, class _Allocator>
699-
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
700-
operator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
701-
702-
template <class _CharT, class _Traits, class _Allocator>
703-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
704-
operator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
705-
706-
template <class _CharT, class _Traits, class _Allocator>
707-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
708-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
709-
710694
template <class _CharT, class _Traits, class _Allocator>
711695
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
712-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
713-
714-
# if _LIBCPP_STD_VER >= 26
715-
716-
template <class _CharT, class _Traits, class _Allocator>
717-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
718-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
719-
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs);
720-
721-
template <class _CharT, class _Traits, class _Allocator>
722-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
723-
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, type_identity_t<basic_string_view<_CharT, _Traits>> __rhs);
724-
725-
template <class _CharT, class _Traits, class _Allocator>
726-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
727-
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
728-
const basic_string<_CharT, _Traits, _Allocator>& __rhs);
729-
730-
template <class _CharT, class _Traits, class _Allocator>
731-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
732-
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs);
733-
734-
# endif
735-
736-
extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
737-
<char, char_traits<char>, allocator<char> >(char const*, string const&);
696+
__concatenate_strings(const _Allocator& __alloc,
697+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str1,
698+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str2);
738699

739700
template <class _Iter>
740701
struct __string_is_trivial_iterator : public false_type {};
@@ -2278,15 +2239,8 @@ private:
22782239
std::__throw_out_of_range("basic_string");
22792240
}
22802241

2281-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&);
2282-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&);
2283-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&);
2284-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*);
2285-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type);
2286-
# if _LIBCPP_STD_VER >= 26
2287-
friend constexpr basic_string operator+ <>(const basic_string&, type_identity_t<__self_view>);
2288-
friend constexpr basic_string operator+ <>(type_identity_t<__self_view>, const basic_string&);
2289-
# endif
2242+
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
2243+
__concatenate_strings<>(const _Allocator&, __type_identity_t<__self_view>, __type_identity_t<__self_view>);
22902244

22912245
template <class _CharT2, class _Traits2, class _Allocator2>
22922246
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>&
39863940

39873941
template <class _CharT, class _Traits, class _Allocator>
39883942
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
3989-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3990-
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3943+
__concatenate_strings(const _Allocator& __alloc,
3944+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str1,
3945+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str2) {
39913946
using _String = basic_string<_CharT, _Traits, _Allocator>;
3992-
auto __lhs_sz = __lhs.size();
3993-
auto __rhs_sz = __rhs.size();
39943947
_String __r(__uninitialized_size_tag(),
3995-
__lhs_sz + __rhs_sz,
3996-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3948+
__str1.size() + __str2.size(),
3949+
_String::__alloc_traits::select_on_container_copy_construction(__alloc));
39973950
auto __ptr = std::__to_address(__r.__get_pointer());
3998-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3999-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4000-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3951+
_Traits::copy(__ptr, __str1.data(), __str1.size());
3952+
_Traits::copy(__ptr + __str1.size(), __str2.data(), __str2.size());
3953+
_Traits::assign(__ptr[__str1.size() + __str2.size()], _CharT());
40013954
return __r;
40023955
}
40033956

3957+
template <class _CharT, class _Traits, class _Allocator>
3958+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
3959+
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3960+
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3961+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
3962+
}
3963+
40043964
template <class _CharT, class _Traits, class _Allocator>
40053965
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
40063966
operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
4007-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4008-
auto __lhs_sz = _Traits::length(__lhs);
4009-
auto __rhs_sz = __rhs.size();
4010-
_String __r(__uninitialized_size_tag(),
4011-
__lhs_sz + __rhs_sz,
4012-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4013-
auto __ptr = std::__to_address(__r.__get_pointer());
4014-
_Traits::copy(__ptr, __lhs, __lhs_sz);
4015-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4016-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4017-
return __r;
3967+
return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
40183968
}
40193969

3970+
extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
3971+
<char, char_traits<char>, allocator<char> >(char const*, string const&);
3972+
40203973
template <class _CharT, class _Traits, class _Allocator>
40213974
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
40223975
operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
4023-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4024-
typename _String::size_type __rhs_sz = __rhs.size();
4025-
_String __r(__uninitialized_size_tag(),
4026-
__rhs_sz + 1,
4027-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4028-
auto __ptr = std::__to_address(__r.__get_pointer());
4029-
_Traits::assign(__ptr, 1, __lhs);
4030-
_Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
4031-
_Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
4032-
return __r;
3976+
return std::__concatenate_strings<_CharT, _Traits>(
3977+
__rhs.get_allocator(), basic_string_view<_CharT, _Traits>(&__lhs, 1), __rhs);
40333978
}
40343979

40353980
template <class _CharT, class _Traits, class _Allocator>
40363981
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
40373982
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
4038-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4039-
typename _String::size_type __lhs_sz = __lhs.size();
4040-
typename _String::size_type __rhs_sz = _Traits::length(__rhs);
4041-
_String __r(__uninitialized_size_tag(),
4042-
__lhs_sz + __rhs_sz,
4043-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4044-
auto __ptr = std::__to_address(__r.__get_pointer());
4045-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4046-
_Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
4047-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4048-
return __r;
3983+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
40493984
}
40503985

40513986
template <class _CharT, class _Traits, class _Allocator>
40523987
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
40533988
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) {
4054-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4055-
typename _String::size_type __lhs_sz = __lhs.size();
4056-
_String __r(__uninitialized_size_tag(),
4057-
__lhs_sz + 1,
4058-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4059-
auto __ptr = std::__to_address(__r.__get_pointer());
4060-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4061-
_Traits::assign(__ptr + __lhs_sz, 1, __rhs);
4062-
_Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
4063-
return __r;
3989+
return std::__concatenate_strings<_CharT, _Traits>(
3990+
__lhs.get_allocator(), __lhs, basic_string_view<_CharT, _Traits>(&__rhs, 1));
3991+
}
3992+
# if _LIBCPP_STD_VER >= 26
3993+
3994+
template <class _CharT, class _Traits, class _Allocator>
3995+
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
3996+
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3997+
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
3998+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
3999+
}
4000+
4001+
template <class _CharT, class _Traits, class _Allocator>
4002+
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
4003+
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4004+
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
4005+
return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
40644006
}
40654007

4008+
# endif // _LIBCPP_STD_VER >= 26
4009+
40664010
# ifndef _LIBCPP_CXX03_LANG
40674011

40684012
template <class _CharT, class _Traits, class _Allocator>
@@ -4113,54 +4057,18 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) {
41134057

41144058
# if _LIBCPP_STD_VER >= 26
41154059

4116-
template <class _CharT, class _Traits, class _Allocator>
4117-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
4118-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4119-
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
4120-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4121-
typename _String::size_type __lhs_sz = __lhs.size();
4122-
typename _String::size_type __rhs_sz = __rhs.size();
4123-
_String __r(__uninitialized_size_tag(),
4124-
__lhs_sz + __rhs_sz,
4125-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4126-
auto __ptr = std::__to_address(__r.__get_pointer());
4127-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4128-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4129-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4130-
return __r;
4131-
}
4132-
41334060
template <class _CharT, class _Traits, class _Allocator>
41344061
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
41354062
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs,
41364063
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
4137-
__lhs.append(__rhs);
4138-
return std::move(__lhs);
4139-
}
4140-
4141-
template <class _CharT, class _Traits, class _Allocator>
4142-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
4143-
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4144-
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
4145-
using _String = basic_string<_CharT, _Traits, _Allocator>;
4146-
typename _String::size_type __lhs_sz = __lhs.size();
4147-
typename _String::size_type __rhs_sz = __rhs.size();
4148-
_String __r(__uninitialized_size_tag(),
4149-
__lhs_sz + __rhs_sz,
4150-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4151-
auto __ptr = std::__to_address(__r.__get_pointer());
4152-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4153-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4154-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4155-
return __r;
4064+
return std::move(__lhs.append(__rhs));
41564065
}
41574066

41584067
template <class _CharT, class _Traits, class _Allocator>
41594068
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
41604069
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
41614070
basic_string<_CharT, _Traits, _Allocator>&& __rhs) {
4162-
__rhs.insert(0, __lhs);
4163-
return std::move(__rhs);
4071+
return std::move(__rhs.insert(0, __lhs));
41644072
}
41654073

41664074
# endif // _LIBCPP_STD_VER >= 26

0 commit comments

Comments
 (0)