This is an archive of the discontinued LLVM Phabricator instance.

llvm::zip should not require assignment operator
AcceptedPublic

Authored by tlongeri on Oct 26 2022, 12:00 PM.

Details

Diff Detail

Event Timeline

tlongeri created this revision.Oct 26 2022, 12:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 26 2022, 12:00 PM
tlongeri requested review of this revision.Oct 26 2022, 12:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 26 2022, 12:00 PM
tlongeri updated this revision to Diff 470985.EditedOct 26 2022, 6:25 PM

Add zip test. Fix tup_inc incorrectly remaining const. Rename increment_or_end to increment_if_not_end.

tlongeri updated this revision to Diff 471021.Oct 26 2022, 10:14 PM

clang-format

dblaikie accepted this revision.Oct 27 2022, 7:57 AM

I've got mixed feelings - the mechanics of the change seem fine, but iterator requirements include copy assignability and copy constructibility - so whatever iterator you're going to use with this feature isn't implementing the iterator requirements and probably should be fixed? I guess the C++20 iterator concepts are a bit more flexible and may include this situation.

This revision is now accepted and ready to land.Oct 27 2022, 7:57 AM

I've got mixed feelings - the mechanics of the change seem fine, but iterator requirements include copy assignability and copy constructibility - so whatever iterator you're going to use with this feature isn't implementing the iterator requirements and probably should be fixed?

It's a good point that we're supporting here iterators that aren't compliant with the general requirements. But I'm wondering if this isn't still a good thing?

That is: isn't it just good for ranges and all adaptors/filters/... to require the minimum amount of things they need from an iterator? (it's not like we're checking on every properties of an iterator everywhere just to force an arbitrary contract).

(we should also fix the iterator if possible, but I know also that some iterators are "fat" and avoiding copies may be valuable!)

I've got mixed feelings - the mechanics of the change seem fine, but iterator requirements include copy assignability and copy constructibility - so whatever iterator you're going to use with this feature isn't implementing the iterator requirements and probably should be fixed?

It's a good point that we're supporting here iterators that aren't compliant with the general requirements. But I'm wondering if this isn't still a good thing?

That is: isn't it just good for ranges and all adaptors/filters/... to require the minimum amount of things they need from an iterator? (it's not like we're checking on every properties of an iterator everywhere just to force an arbitrary contract).

(we should also fix the iterator if possible, but I know also that some iterators are "fat" and avoiding copies may be valuable!)

Yeah, that's roughly my thinking on approving this.

tlongeri added a comment.EditedOct 27 2022, 3:37 PM

I've got mixed feelings - the mechanics of the change seem fine, but iterator requirements include copy assignability and copy constructibility - so whatever iterator you're going to use with this feature isn't implementing the iterator requirements and probably should be fixed?

I missed this, to be honest. The context is just that I tried and failed to zip MLIR's ElementsAttrIterator, and I saw no reason why zip needed assignment.

I guess the C++20 iterator concepts are a bit more flexible and may include this situation.

Unfortunately, it looks like the C++20 input_or_output_iterator concept still requires move assignability (through -> weakly_incrementable -> movable)

Isn't it still a small improvement, though? Besides what Mehdi said, I would just add that it still seems like incrementing the iterators in-place is a bit better. Maybe I should adjust the description, though.

Edit: didn't see your reply

I've got mixed feelings - the mechanics of the change seem fine, but iterator requirements include copy assignability and copy constructibility - so whatever iterator you're going to use with this feature isn't implementing the iterator requirements and probably should be fixed?

I missed this, to be honest. The context is just that I tried and failed to zip MLIR's ElementsAttrIterator, and I saw no reason why zip needed assignment.

I guess the C++20 iterator concepts are a bit more flexible and may include this situation.

Unfortunately, it looks like the C++20 input_or_output_iterator concept still requires move assignability (through -> weakly_incrementable -> movable)

Yeah - though I think the existing code before your patch here requires copy constructibliity - so this patch does fix llvm::zip to work with these newer iterator concepts, which is good.

Isn't it still a small improvement, though? Besides what Mehdi said, I would just add that it still seems like incrementing the iterators in-place is a bit better. Maybe I should adjust the description, though.

Yep - might be worth checking the ElementsAttrIterator to ensure it at least meets the newer iterator concepts at least. (my usual concern here is not that changing one algorithm to be more lenient - but that a non-conforming iterator will run up against other problems, standard algorithms will have difficult/might have more stringent checks, etc).

Yep - might be worth checking the ElementsAttrIterator to ensure it at least meets the newer iterator concepts at least.

On top of the patch here, we're also adding copy construction and copy assignment on ElementsAttrIterator by the way, it seems like reasonable addition and it seems like it was an oversight to not have it there (this particular iterator isn't that "fat": two bools and two pointers).

Yep - might be worth checking the ElementsAttrIterator to ensure it at least meets the newer iterator concepts at least.

On top of the patch here, we're also adding copy construction and copy assignment on ElementsAttrIterator by the way, it seems like reasonable addition and it seems like it was an oversight to not have it there (this particular iterator isn't that "fat": two bools and two pointers).

Awesome - thanks for the details!