Skip to content
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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2d606f4
[libc++][strings] P2591R5: Concatenation of strings and string views
H-G-Hristov Apr 11, 2024
af56ab9
Implemented tests
H-G-Hristov Apr 11, 2024
474d5b9
Cleanup
H-G-Hristov Apr 11, 2024
38f6e85
Restored formatting
H-G-Hristov Apr 11, 2024
ea270b6
Addressed review comments
H-G-Hristov Apr 13, 2024
292cd8f
Removed `constexpr_char_traits` tests
H-G-Hristov Apr 13, 2024
f312052
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Apr 13, 2024
9a86ea1
Use Will Hawkins implementation
H-G-Hristov Apr 15, 2024
695b4b6
Cleanup
H-G-Hristov Apr 15, 2024
2df55a5
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Apr 15, 2024
6b77e5a
Reordered forward declared functions
H-G-Hristov Apr 16, 2024
92d08d6
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov May 9, 2024
694e6fd
Fixed rvalue argument overload
H-G-Hristov May 9, 2024
be56164
Workaround for `constexpr_char_traits` not compatible with literals
H-G-Hristov May 10, 2024
20b9120
Minor cleanup
H-G-Hristov May 10, 2024
a8c28fb
Fixed formatting
H-G-Hristov May 10, 2024
16fcbba
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov May 10, 2024
bdbaf38
Cleanup
H-G-Hristov May 10, 2024
5d804f5
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov May 10, 2024
6e4d6b4
Merge branch 'hgh/libcxx/P2591R5-Concatenation-of-string-and-string-v…
H-G-Hristov May 10, 2024
9f27ece
Try to fix ASAN tests
H-G-Hristov May 10, 2024
43c78be
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
Zingam May 10, 2024
d56da5f
Add a workaround note
H-G-Hristov May 16, 2024
f4f26df
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Jul 10, 2024
da99993
Fixed formatting
H-G-Hristov Jul 10, 2024
907bcc4
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
Zingam Jul 10, 2024
a7bf9a0
WIP - tests with convertible to `string_view`
H-G-Hristov Jul 14, 2024
13d58fe
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Jul 14, 2024
d214ef1
Added ConvertibleToStringView test
H-G-Hristov Jul 14, 2024
20f39e1
Cleanup
H-G-Hristov Jul 14, 2024
666cb62
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Jul 14, 2024
e5e808f
Fixes
H-G-Hristov Jul 14, 2024
d799472
Addressed comments
H-G-Hristov Jul 16, 2024
0820ad9
Merge branch 'main' into hgh/libcxx/P2591R5-Concatenation-of-string-a…
H-G-Hristov Jul 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_sstream_from_string_view`` ``202306L``
---------------------------------------------------------- -----------------
``__cpp_lib_string_view`` ``202403L``
---------------------------------------------------------- -----------------
``__cpp_lib_submdspan`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_text_encoding`` *unimplemented*
Expand Down
1 change: 1 addition & 0 deletions libcxx/docs/ReleaseNotes/19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Implemented Papers
- P2872R3 - Remove ``wstring_convert`` From C++26
- P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
- P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
- P2591R5 - Concatenation of strings and string views
- P2968R2 - Make ``std::ignore`` a first-class object
- P2302R4 - ``std::ranges::contains``
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cPapers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"`P2845R8 <https://wg21.link/P2845R8>`__","LWG","Formatting of ``std::filesystem::path``","Tokyo March 2024","","","|format|"
"`P0493R5 <https://wg21.link/P0493R5>`__","LWG","Atomic minimum/maximum","Tokyo March 2024","","",""
"`P2542R8 <https://wg21.link/P2542R8>`__","LWG","``views::concat``","Tokyo March 2024","","","|ranges|"
"`P2591R5 <https://wg21.link/P2591R5>`__","LWG","Concatenation of strings and string views","Tokyo March 2024","","",""
"`P2591R5 <https://wg21.link/P2591R5>`__","LWG","Concatenation of strings and string views","Tokyo March 2024","|Complete|","19.0",""
"`P2248R8 <https://wg21.link/P2248R8>`__","LWG","Enabling list-initialization for algorithms","Tokyo March 2024","","",""
"`P2810R4 <https://wg21.link/P2810R4>`__","LWG","``is_debugger_present`` ``is_replaceable``","Tokyo March 2024","","",""
"`P1068R11 <https://wg21.link/P1068R11>`__","LWG","Vector API for random number generation","Tokyo March 2024","","",""
Expand Down
98 changes: 98 additions & 0 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -687,6 +705,28 @@ 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);

Copy link
Member

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.

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&);

Expand Down Expand Up @@ -2150,6 +2190,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
Expand Down Expand Up @@ -4007,6 +4051,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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether it would be better to drop std::move() here as __lhs is move-eligible here (ditto below).

Copy link
Contributor Author

@H-G-Hristov H-G-Hristov Apr 13, 2024

Choose a reason for hiding this comment

The 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>
Expand Down
5 changes: 4 additions & 1 deletion libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ __cpp_lib_stdatomic_h 202011L <stdatomic.h>
__cpp_lib_string_contains 202011L <string> <string_view>
__cpp_lib_string_resize_and_overwrite 202110L <string>
__cpp_lib_string_udls 201304L <string>
__cpp_lib_string_view 201803L <string> <string_view>
__cpp_lib_string_view 202403L <string> <string_view>
201803L // C++20
201606L // C++17
__cpp_lib_submdspan 202306L <mdspan>
__cpp_lib_syncbuf 201803L <syncstream>
Expand Down Expand Up @@ -547,6 +548,8 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_span_at 202311L
# define __cpp_lib_span_initializer_list 202311L
# define __cpp_lib_sstream_from_string_view 202306L
# undef __cpp_lib_string_view
# define __cpp_lib_string_view 202403L
// # define __cpp_lib_submdspan 202306L
// # define __cpp_lib_text_encoding 202306L
# undef __cpp_lib_to_chars
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
__cpp_lib_string_udls 201304L [C++14]
__cpp_lib_string_view 201606L [C++17]
201803L [C++20]
202403L [C++26]
__cpp_lib_to_string 202306L [C++26]
*/

Expand Down Expand Up @@ -483,8 +484,8 @@
# ifndef __cpp_lib_string_view
# error "__cpp_lib_string_view should be defined in c++26"
# endif
# if __cpp_lib_string_view != 201803L
# error "__cpp_lib_string_view should have the value 201803L in c++26"
# if __cpp_lib_string_view != 202403L
# error "__cpp_lib_string_view should have the value 202403L in c++26"
# endif

# if !defined(_LIBCPP_VERSION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
__cpp_lib_string_contains 202011L [C++23]
__cpp_lib_string_view 201606L [C++17]
201803L [C++20]
202403L [C++26]
*/

#include <string_view>
Expand Down Expand Up @@ -252,8 +253,8 @@
# ifndef __cpp_lib_string_view
# error "__cpp_lib_string_view should be defined in c++26"
# endif
# if __cpp_lib_string_view != 201803L
# error "__cpp_lib_string_view should have the value 201803L in c++26"
# if __cpp_lib_string_view != 202403L
# error "__cpp_lib_string_view should have the value 202403L in c++26"
# endif

#endif // TEST_STD_VER > 23
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
__cpp_lib_string_udls 201304L [C++14]
__cpp_lib_string_view 201606L [C++17]
201803L [C++20]
202403L [C++26]
__cpp_lib_submdspan 202306L [C++26]
__cpp_lib_syncbuf 201803L [C++20]
__cpp_lib_text_encoding 202306L [C++26]
Expand Down Expand Up @@ -7894,8 +7895,8 @@
# ifndef __cpp_lib_string_view
# error "__cpp_lib_string_view should be defined in c++26"
# endif
# if __cpp_lib_string_view != 201803L
# error "__cpp_lib_string_view should have the value 201803L in c++26"
# if __cpp_lib_string_view != 202403L
# error "__cpp_lib_string_view should have the value 202403L in c++26"
# endif

# if !defined(_LIBCPP_VERSION)
Expand Down
Loading