-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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++] Implement views::join_with
#65536
base: main
Are you sure you want to change the base?
Conversation
3259db4
to
0481670
Compare
0481670
to
f113229
Compare
@JMazurkiewicz Please ping us when this is ready to review and make it a non-draft. |
f113229
to
1835f68
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
I guess with constexpr variant this cool feature can be finalized now :) |
a84985a
to
fcdf64a
Compare
54a741c
to
a9a1031
Compare
a9a1031
to
9406093
Compare
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i) | ||
requires _Const && convertible_to<iterator_t<_View>, _OuterIter> && | ||
convertible_to<iterator_t<_InnerRng>, _InnerIter> && convertible_to<iterator_t<_Pattern>, _PatternIter> | ||
: __parent_(__i.__parent_), __outer_it_(std::move(__i.__outer_it_)) { |
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.
I think there is something wrong. __iterator<false>
is not a friend of __iterator<true>
, so in theory this should not compile because of accessing private members.
This probably indicates that this function is not tested
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.
I think there is something wrong.
__iterator<false>
is not a friend of__iterator<true>
, so in theory this should not compile because of accessing private members.This probably indicates that this function is not tested
I think that everything is OK here. Even though __iterator<false>
is not a friend of __iterator<true>
, its members can still be accessed thanks to friend join_with_view
declaration. Per [class.friend]/2:
Declaring a class to be a friend implies that private and protected members of the class granting friendship can be named in the base-specifiers and member declarations of the befriended class.
__iterator<false>
declares join_with_view
to be a friend, which means that member declarations of it (__iterator<true>
and __sentinel<?>
) can access iterator's private members.
auto it = jwv.begin(); | ||
assert(*it == 1); | ||
|
||
using CIter = std::ranges::iterator_t<const decltype(jwv)>; |
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.
Could you please
static_assert(!std::is_same_v<Iter, CIter>);
I think this test is not testing what it is supposed to test. I suspect it
and cit
are both iterator<true>
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.
Added here: 14471bc
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s) | ||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> | ||
: __end_(std::move(__s.__end_)) {} |
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.
same as iterator
, I think __sentinel<false>
is not a friend of __sentinel<true>
so this should not compile. And it is an indication of missing tests.
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.
I think that [class.friend]/2 applies here too.
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> | ||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool | ||
operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { | ||
return __x.__get_outer() == __y.__end_; |
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.
again. __get_outer
is private
and I don't think sentinel
has been befriended to iterator
. This should not compile in theory. possible missing tests as well
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.
You are right here, operator==
is a friend of sentinel
only, so it should not be able to access iterator
's private members. Unluckily, both clang and gcc accept this incorrect code.
Fixed here: 9760ec3
|
||
// <ranges> | ||
|
||
// iterator() = default; |
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.
we usually have another test point to test this is not explicit.
Iter iter = {};
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.
Added here: 3771be9
|
||
// <ranges> | ||
|
||
// friend constexpr void iter_swap(const iterator& x, const iterator& y); |
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 we have a test to test that it delicates to underlying's tier_swap
? i.e. not doing ranges::swap(*it1, *it2)
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.
Done! 19e4fa2
std::ranges::join_with_view jwv(vec, 0); | ||
using JWV = decltype(jwv); | ||
static_assert(!std::ranges::common_range<JWV>); | ||
using CSent = std::ranges::sentinel_t<const JWV>; |
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 we static_assert(!std::same_as<Sent, CSent>)
to make sure we are testing what we are supposed to test
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.
Added here: d52bdbf
|
||
// template<bool OtherConst> | ||
// requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>> | ||
// friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y); |
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 we make sure we static_assert(!same_as<Iter, CIter>)
and static_assert(!same_as<Sent, CSent>)
and make sure we test all the combinations
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.
Added here: 96eae0b
|
||
// <ranges> | ||
|
||
// join_with_view() |
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.
we usually have a test to test the explicitness
join_with_view<...> jwv = {};
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.
Added: 4ab1ee2
} | ||
} | ||
|
||
constexpr void test_end() {} |
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.
why is this needed?
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.
It's not, I forgot to remove it earlier (fb5ab01).
@JMazurkiewicz At the top you mention that this PR completed several papers. Do you need to add additional GitHub issues to the list that this PR closes/fixes/? |
Instead of `// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20`
views::join_with
" (https://wg21.link/P2441R2), closes P2441R2:views::join_with
#105185compatible-joinable-ranges
is underconstrained #105346views
explicit
#105252iterators
for proper flattening #105250