-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Implement P2538R1 "ADL-proof std::projected" #65411
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
Conversation
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 don' think this builds.
include/c++/v1/__iterator/projected.h:49:8: error: class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used [-Wunusable-partial-specialization]
49 | struct incrementable_traits<projected<_It, _Proj>> {
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.
None of the tests included with this change actually work.
They're all missing the include for TEST_STD_VER
, which disables the tests.
But after re-enabling the tests and removing the fix, all the tests still passed.
Do you know what's going on there?
@@ -80,3 +80,11 @@ struct BadPredicate6 { | |||
bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete; | |||
}; | |||
static_assert(!std::indirect_binary_predicate<BadPredicate6, It1, It2>); | |||
|
|||
// Test ADL-proofing (P2538R1) | |||
#if TEST_STD_VER >= 26 |
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 are we not testing this in older dialectts?
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.
These tests pass before your change as well.
Also you're missing an include for test_macros.h
, so this test was never running.
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.
Good catch with the test_macros.h
.
Why are we not testing this in older dialectts?
This is technically a C++26 paper, so I was going to test this only in C++26. The fact that it happens to pass in C++20/23 is just because we will implement projected
the same in all standard modes, but we're not technically guaranteeing that projected
is ADL-proof in older standards. Does that make sense?
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.
Regarding test_macros.h
, -Wundef
actually catches those!
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.
This very much feels like a defect report. I would rather we test the behavior in all dialects where we provide the behavior.
template <weakly_incrementable _It, class _Proj> | ||
struct incrementable_traits<projected<_It, _Proj>> { | ||
using difference_type = iter_difference_t<_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.
It's strange that this (no longer valid) partial specialization is not removed.
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.
Yeah it should be removed, thanks for the heads up. I basically just took https://reviews.llvm.org/D119029 and did a few changes I could spot, uploaded it here and closed the Phab revision. I'll address this.
f3e9988
to
23567ab
Compare
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.
LGTM but I would like to see the tests backported to all the dialects where projected is available.
I'll test our implementation in all standard modes, but I won't make the tests unconditional on the standard version. This is a c++26 paper, so a conforming C++20 or C++23 implementation should be able to pass our test suite without implementing that paper. |
23567ab
to
5fb0cf8
Compare
Notice that because Holder<Incomplete> is _possible_ to complete, but _unsafe_ to complete, that means that Holder<Incomplete>* is basically not an iterator and it's not even safe to ask if input_iterator<Holder<Incomplete>*> because that _will_ necessarily complete the type. So it's totally expected that we still cannot safely ask e.g. static_assert(std::indirect_unary_predicate<bool(&)(Holder<Incomplete>&), Holder<Incomplete>*>); or even static_assert(!std::indirect_unary_predicate<int, Holder<Incomplete>*>); Differential Revision: https://reviews.llvm.org/D119029 Co-authored-by: Louis Dionne <[email protected]>
5fb0cf8
to
a6e632a
Compare
Notice that because Holder<Incomplete> is _possible_ to complete, but _unsafe_ to complete, that means that Holder<Incomplete>* is basically not an iterator and it's not even safe to ask if input_iterator<Holder<Incomplete>*> because that _will_ necessarily complete the type. So it's totally expected that we still cannot safely ask e.g. static_assert(std::indirect_unary_predicate<bool(&)(Holder<Incomplete>&), Holder<Incomplete>*>); or even static_assert(!std::indirect_unary_predicate<int, Holder<Incomplete>*>); This was originally uploaded as https://reviews.llvm.org/D119029 and I picked it up here as part of the Github PR transition. Co-authored-by: Arthur O'Dwyer <[email protected]>
Notice that because Holder is possible to complete, but unsafe to complete, that means that Holder* is basically not an iterator and it's not even safe to ask if input_iterator<Holder*> because that will necessarily complete the type. So it's totally expected that we still cannot safely ask e.g.
static_assert(std::indirect_unary_predicate<bool(&)(Holder&), Holder*>);
or even
static_assert(!std::indirect_unary_predicate<int, Holder*>);
This was originally uploaded as https://reviews.llvm.org/D119029 and I picked it up here as part of the Github PR transition.