Details
- Reviewers
ldionne EricWF Mordante zoecarver - Group Reviewers
Restricted Project - Commits
- rG9816d43cff5a: [libcxx] adds `iter_difference_t` and `iter_value_t`
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libcxx/include/iterator | ||
---|---|---|
440 | Can we get rid of the __extract_iter_value_t struct alltogether and always fall back to an alias? template<class _Ip> requires __is_primary_template<iterator_traits<remove_cvref_t<_Ip>>>::value && __has_member_value_type<indirectly_readable_traits<remove_cvref_t<_Ip>>> using iter_value_t = typename indirectly_readable_traits<remove_cvref_t<_Ip>>::value_type; template<class _Ip> using iter_value_t = typename iterator_traits<remove_cvref_t<_Ip>>::value_type; That way we would get around all those type instantiations, which are quite costly | |
447 | This should be class | |
449 | The __has_integral_minus Is not obvious should have add a comment? |
libcxx/include/iterator | ||
---|---|---|
445 | For consistency, please add backticks around indirectly_readable_traits<R[I]>::value_type. | |
454 | For consistency, please add backticks around iterator_traits<R[I]>::value_type. | |
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.fail.cpp | ||
19 ↗ | (On Diff #335166) | Why not use a specific offset like expected-errror@-1? |
libcxx/include/iterator | ||
---|---|---|
449 | Please disregard, read the other patch |
libcxx/include/iterator | ||
---|---|---|
440 | Aliases can't be specialised. Might be worth a compiler patch to elide this if it's deemed too costly? | |
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.fail.cpp | ||
19 ↗ | (On Diff #335166) | The error originates from <iterator>, not this file (I originally did expected-error@-1 which is how I learnt about @iterator:* when it failed). |
libcxx/include/iterator | ||
---|---|---|
449 | I can't find your comment anywhere else? |
libcxx/include/iterator | ||
---|---|---|
438–439 | Slightly disentangled: so that code doesn't interrupt the flow of an English sentence, and the primary template isn't forward-declared. I think this is fine; but it does feel weird at a higher level that http://eel.is/c++draft/sequences#general-2 already defines __iter_value_type (as an exposition-only implementation detail related to container deduction guides), and here http://eel.is/c++draft/readable.traits#2 is introducing iter_value_t with a subtly different meaning. libc++ maintainers will have to be careful to pick the right one. | |
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.fail.cpp | ||
32 ↗ | (On Diff #335172) | FWIW, I think it would make more sense to cast all these tests in terms of what we do expect to be true, instead of relying on compiler error messages. template<class T> auto has_no_difference_type(int) -> std::void_t<std::iter_difference_t<T>> {} template<class T> bool has_no_difference_type(long) { return true; } int main(int, char**) { assert(has_no_difference_type<void_subtraction>(42)); return 0; } But this is assuming that iter_difference_t<T> is supposed to be SFINAE-friendly. I don't know if that's actually guaranteed/intended by the Standard. |
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.pass.cpp | ||
24–45 | FWIW, this indentation is insane. |
libcxx/include/iterator | ||
---|---|---|
438–439 | The mixing of standardese with code was intentional, to show which bits of code correspond to which bits of the standard. This idea was taken from <type_traits>. In future, for something as trivial as this, please request what you're after instead of providing a full-blown suggested edit.
I think the best thing to do would be to ask LWG to consider renaming iter-value-type to something else (it might even be possible to do this editorially after a mailing discussion), or us just doing so regardless of what LWG thinks, so as to avoid confusion. | |
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.fail.cpp | ||
32 ↗ | (On Diff #335172) | The wording is SFINAE-friendly, but my implementation here wasn't due to a mistake in translating from cjdb-ranges to libc++. |
libcxx/include/iterator | ||
---|---|---|
445 | Please write RI, not R[I]. (I know you're trying to reflect that the I in the standard is a subscript letter. However, it's not an array index, and RI functions semantically as a single identifier — there is no separate entity R to be discussed, so we don't need a name for it.) I don't think you should be instantiating incrementable_traits<RI> in the case that iterator_traits<RI> is the primary template. Please (1) check what the Standard's intent here is, (2) make the fix if needed, and (3) add a test case that detects the fix. Separately and presumably a moot point in this case: note that conditional_t is compile-time-wasting by design. Anywhere in libc++ that we need its effects and aren't mandated to use conditional_t, we should be using Eric's _If<is-blah, incr-traits, iter-traits> because it instantiates fewer templates. |
libcxx/include/iterator | ||
---|---|---|
445 |
It's pretty much left up to us. MSVC's implementation is identical to the conditional_t one, for example, and @CaseyCarter understands the intention better than us all. |
libcxx/include/iterator | ||
---|---|---|
440 | This now has a mix of RI and R[I] | |
445 |
What does this even mean? How do you produce incrementable_traits<RI>::difference_type without instantiating incrementable_traits<RI>? |
libcxx/include/iterator | ||
---|---|---|
445 | I flipped the logic by accident. I should have said, don't instantiate incrementable_traits<RI> in the case that iterator_traits<RI> is not the primary template, i.e. in the case when we want to just go ahead and trust iterator_traits<RI>::value_type. (And I almost made the exact same error again in typing up this message! Note to self: Here "primary" means "the one we don't want to use.") |
@cjdb wrote:
reverts _If to conditional_t to avoid substitution failure problem in future commits
Is this because of Clang bug https://bugs.llvm.org/show_bug.cgi?id=44833#c5 ? If so, that Clang bug is probably going to block a lot of Ranges implementation until it's fixed, anyway. @ldionne, do you have any guidance here? (1) Should libc++ aim to be the one standard library that works around this Clang bug, or should we just pressure Clang to fix their bug? (2) In the short term, assuming the bug won't be fixed tomorrow, how much should Chris work around Clang bugs in these patches versus just delaying the patches until Clang is ready?
I think we need to push hard on Clang to fix this bug. If working around it for now is feasible then let's do that, but I would not go too far in that direction.
I think this LGTM. There's some small comments about a missed R[I] -> RI transformation, but I think that's all. LGTM with nitpicks applied.
libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.pass.cpp | ||
---|---|---|
24–45 | Can we please keep comments constructive and polite? It's fine to disagree with the way of formatting things. It's also fine to request changes on a patch due to indentation or some other format-related issue that impacts readability. But please try to root your comment in something objective. |
Merged ahead of CI reaching 100% with permission from @ldionne. Apparently only the santatizers, macos, gcc, c++03, and C++20 builds are the most important.
Slightly disentangled: so that code doesn't interrupt the flow of an English sentence, and the primary template isn't forward-declared.
I think this is fine; but it does feel weird at a higher level that http://eel.is/c++draft/sequences#general-2 already defines __iter_value_type (as an exposition-only implementation detail related to container deduction guides), and here http://eel.is/c++draft/readable.traits#2 is introducing iter_value_t with a subtly different meaning. libc++ maintainers will have to be careful to pick the right one.