This is an archive of the discontinued LLVM Phabricator instance.

Add `all_of_zip` to STLExtras
ClosedPublic

Authored by mehdi_amini on Jul 22 2021, 3:10 PM.

Details

Summary

This takes two ranges and invokes a predicate on the element-wise pair in the
ranges. It returns true if all the pairs are matching the predicate and the ranges
have the same size.
It is useful with containers that aren't random iterator where we can't check the
sizes in O(1).

Diff Detail

Event Timeline

mehdi_amini created this revision.Jul 22 2021, 3:10 PM
mehdi_amini requested review of this revision.Jul 22 2021, 3:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 22 2021, 3:10 PM
rriddle added inline comments.
llvm/include/llvm/ADT/STLExtras.h
1724

The name here feels a bit weird. This is essentially just std::ranges::equal/std::equal with special size mismatch behavior. Can we name it something closer to what it would be replaced by? Also, in what situations is the size mismatch result needed (i.e. the llvm::None)?

mehdi_amini added inline comments.Jul 23 2021, 11:16 AM
llvm/include/llvm/ADT/STLExtras.h
1724

I was trying to differentiate between "length mismatch" and "element mismatch", but maybe we don't need to?

Seems like a bit of a narrow use case combination of two features - is there much missing/a way we could generalize the more general tools so they could be composed easily enough in the cases where the combination is desirable?

The issue is that I think the "expected" way in C++ to have a zip operator that fails when the length mismatch is to use exceptions. I'm not how else to have a range that can fail when iterated on?

The issue is that I think the "expected" way in C++ to have a zip operator that fails when the length mismatch is to use exceptions. I'm not how else to have a range that can fail when iterated on?

Yeah, while keeping the iterator interface (rather than using a different interface, which would then be less composable) and with arbitrary elements (so you can't construct a default/failed object) it's a bit limited.

What about if the range itself was boolean testable (or had some "areBothRangesTraversed" operation or the like) that could be queried (assert-fails if queried early) after the zip has reached the end (and in that case the end would be the end of either range, whichever comes first)?

What about if the range itself was boolean testable (or had some "areBothRangesTraversed" operation or the like) that could be queried (assert-fails if queried early) after the zip has reached the end (and in that case the end would be the end of either range, whichever comes first)?

That's interesting: the range itself is disconnected from the iterator state though, so I don't think you could just query the range.

The best I can think of would be something that would end-up looking like:

auto range = zip(a, b, c);
auto it = range.begin();
for (; it != range.end(); ++it) {
   ...
}
if (!it.all_equals(range.end())  // bike shed the API name
   // error

Augment zip_common with a comparator to test for complete equality of the zipped iterators

I suspect for this case you just want this D106913 right?

I suspect for this case you just want this D106913 right?

LGTM

What about if the range itself was boolean testable (or had some "areBothRangesTraversed" operation or the like) that could be queried (assert-fails if queried early) after the zip has reached the end (and in that case the end would be the end of either range, whichever comes first)?

That's interesting: the range itself is disconnected from the iterator state though, so I don't think you could just query the range.

The best I can think of would be something that would end-up looking like:

auto range = zip(a, b, c);
auto it = range.begin();
for (; it != range.end(); ++it) {
   ...
}
if (!it.all_equals(range.end())  // bike shed the API name
   // error

Ah, yeah, fair enough. Looks OK.

Though I worry about the likely combinatorial expansion of the ultimate API, still - all_of_zip implies the likely existence of none_of_zip and any_of_zip - which admittedly can be defined in terms of one another, so it's not loads of duplication... eh, maybe that's OK then, if they get created.

Carry on!

This revision was not accepted when it landed; it landed in state Needs Review.Jul 28 2021, 10:00 PM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.