Skip to content

Commit 3e61c1a

Browse files
authored
[libc++] Avoid code duplication in strings operator+ overloads (#126048)
1 parent 888c099 commit 3e61c1a

File tree

1 file changed

+49
-141
lines changed

1 file changed

+49
-141
lines changed

libcxx/include/string

Lines changed: 49 additions & 141 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 {};
@@ -2425,15 +2386,8 @@ private:
24252386
std::__throw_out_of_range("basic_string");
24262387
}
24272388

2428-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&);
2429-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&);
2430-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&);
2431-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*);
2432-
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type);
2433-
# if _LIBCPP_STD_VER >= 26
2434-
friend constexpr basic_string operator+ <>(const basic_string&, type_identity_t<__self_view>);
2435-
friend constexpr basic_string operator+ <>(type_identity_t<__self_view>, const basic_string&);
2436-
# endif
2389+
friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
2390+
__concatenate_strings<>(const _Allocator&, __type_identity_t<__self_view>, __type_identity_t<__self_view>);
24372391

24382392
template <class _CharT2, class _Traits2, class _Allocator2>
24392393
friend inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
@@ -3815,83 +3769,73 @@ operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>&
38153769

38163770
template <class _CharT, class _Traits, class _Allocator>
38173771
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
3818-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3819-
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3772+
__concatenate_strings(const _Allocator& __alloc,
3773+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str1,
3774+
__type_identity_t<basic_string_view<_CharT, _Traits> > __str2) {
38203775
using _String = basic_string<_CharT, _Traits, _Allocator>;
3821-
auto __lhs_sz = __lhs.size();
3822-
auto __rhs_sz = __rhs.size();
38233776
_String __r(__uninitialized_size_tag(),
3824-
__lhs_sz + __rhs_sz,
3825-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3777+
__str1.size() + __str2.size(),
3778+
_String::__alloc_traits::select_on_container_copy_construction(__alloc));
38263779
auto __ptr = std::__to_address(__r.__get_pointer());
3827-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3828-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3829-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3780+
_Traits::copy(__ptr, __str1.data(), __str1.size());
3781+
_Traits::copy(__ptr + __str1.size(), __str2.data(), __str2.size());
3782+
_Traits::assign(__ptr[__str1.size() + __str2.size()], _CharT());
38303783
return __r;
38313784
}
38323785

3786+
template <class _CharT, class _Traits, class _Allocator>
3787+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
3788+
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3789+
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3790+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
3791+
}
3792+
38333793
template <class _CharT, class _Traits, class _Allocator>
38343794
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
38353795
operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3836-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3837-
auto __lhs_sz = _Traits::length(__lhs);
3838-
auto __rhs_sz = __rhs.size();
3839-
_String __r(__uninitialized_size_tag(),
3840-
__lhs_sz + __rhs_sz,
3841-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
3842-
auto __ptr = std::__to_address(__r.__get_pointer());
3843-
_Traits::copy(__ptr, __lhs, __lhs_sz);
3844-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3845-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3846-
return __r;
3796+
return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
38473797
}
38483798

3799+
extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
3800+
<char, char_traits<char>, allocator<char> >(char const*, string const&);
3801+
38493802
template <class _CharT, class _Traits, class _Allocator>
38503803
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
38513804
operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3852-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3853-
typename _String::size_type __rhs_sz = __rhs.size();
3854-
_String __r(__uninitialized_size_tag(),
3855-
__rhs_sz + 1,
3856-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
3857-
auto __ptr = std::__to_address(__r.__get_pointer());
3858-
_Traits::assign(__ptr, 1, __lhs);
3859-
_Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
3860-
_Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
3861-
return __r;
3805+
return std::__concatenate_strings<_CharT, _Traits>(
3806+
__rhs.get_allocator(), basic_string_view<_CharT, _Traits>(&__lhs, 1), __rhs);
38623807
}
38633808

38643809
template <class _CharT, class _Traits, class _Allocator>
3865-
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
3810+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
38663811
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
3867-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3868-
typename _String::size_type __lhs_sz = __lhs.size();
3869-
typename _String::size_type __rhs_sz = _Traits::length(__rhs);
3870-
_String __r(__uninitialized_size_tag(),
3871-
__lhs_sz + __rhs_sz,
3872-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3873-
auto __ptr = std::__to_address(__r.__get_pointer());
3874-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3875-
_Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
3876-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3877-
return __r;
3812+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
38783813
}
38793814

38803815
template <class _CharT, class _Traits, class _Allocator>
38813816
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>
38823817
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) {
3883-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3884-
typename _String::size_type __lhs_sz = __lhs.size();
3885-
_String __r(__uninitialized_size_tag(),
3886-
__lhs_sz + 1,
3887-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3888-
auto __ptr = std::__to_address(__r.__get_pointer());
3889-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3890-
_Traits::assign(__ptr + __lhs_sz, 1, __rhs);
3891-
_Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
3892-
return __r;
3818+
return std::__concatenate_strings<_CharT, _Traits>(
3819+
__lhs.get_allocator(), __lhs, basic_string_view<_CharT, _Traits>(&__rhs, 1));
3820+
}
3821+
# if _LIBCPP_STD_VER >= 26
3822+
3823+
template <class _CharT, class _Traits, class _Allocator>
3824+
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
3825+
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3826+
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
3827+
return std::__concatenate_strings<_CharT, _Traits>(__lhs.get_allocator(), __lhs, __rhs);
3828+
}
3829+
3830+
template <class _CharT, class _Traits, class _Allocator>
3831+
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
3832+
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
3833+
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3834+
return std::__concatenate_strings<_CharT, _Traits>(__rhs.get_allocator(), __lhs, __rhs);
38933835
}
38943836

3837+
# endif // _LIBCPP_STD_VER >= 26
3838+
38953839
# ifndef _LIBCPP_CXX03_LANG
38963840

38973841
template <class _CharT, class _Traits, class _Allocator>
@@ -3942,54 +3886,18 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) {
39423886

39433887
# if _LIBCPP_STD_VER >= 26
39443888

3945-
template <class _CharT, class _Traits, class _Allocator>
3946-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
3947-
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3948-
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
3949-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3950-
typename _String::size_type __lhs_sz = __lhs.size();
3951-
typename _String::size_type __rhs_sz = __rhs.size();
3952-
_String __r(__uninitialized_size_tag(),
3953-
__lhs_sz + __rhs_sz,
3954-
_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3955-
auto __ptr = std::__to_address(__r.__get_pointer());
3956-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3957-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3958-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3959-
return __r;
3960-
}
3961-
39623889
template <class _CharT, class _Traits, class _Allocator>
39633890
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
39643891
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs,
39653892
type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) {
3966-
__lhs.append(__rhs);
3967-
return std::move(__lhs);
3968-
}
3969-
3970-
template <class _CharT, class _Traits, class _Allocator>
3971-
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
3972-
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
3973-
const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3974-
using _String = basic_string<_CharT, _Traits, _Allocator>;
3975-
typename _String::size_type __lhs_sz = __lhs.size();
3976-
typename _String::size_type __rhs_sz = __rhs.size();
3977-
_String __r(__uninitialized_size_tag(),
3978-
__lhs_sz + __rhs_sz,
3979-
_String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
3980-
auto __ptr = std::__to_address(__r.__get_pointer());
3981-
_Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3982-
_Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3983-
_Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3984-
return __r;
3893+
return std::move(__lhs.append(__rhs));
39853894
}
39863895

39873896
template <class _CharT, class _Traits, class _Allocator>
39883897
_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator>
39893898
operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
39903899
basic_string<_CharT, _Traits, _Allocator>&& __rhs) {
3991-
__rhs.insert(0, __lhs);
3992-
return std::move(__rhs);
3900+
return std::move(__rhs.insert(0, __lhs));
39933901
}
39943902

39953903
# endif // _LIBCPP_STD_VER >= 26

0 commit comments

Comments
 (0)