[PATCH] D144503: [WIP][STLExtras] Allow `llvm::enumerate` to enumerate over multiple ranges

David Blaikie via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 22 14:25:13 PST 2023


dblaikie added a comment.

In D144503#4142911 <https://reviews.llvm.org/D144503#4142911>, @kuhar wrote:

> In D144503#4142824 <https://reviews.llvm.org/D144503#4142824>, @dblaikie wrote:
>
>> In D144503#4142807 <https://reviews.llvm.org/D144503#4142807>, @kuhar wrote:
>>
>>> Can you give an example? I don't see how this would work. My starting point is that I would like to enable this: `for (auto [Idx, X, Y, Z] : ...(Xs, Ys, Zs)...)`.
>>>
>>> If we tried to compose `enumerate` and `zip_equal`, we would end up with `flatten` used like this: `for (auto [Idx, X, Y, Z] : flatten(enumerate(zip_equal(Xs, Ys, Zs))))`. Here flatten would have to a `map_range`-style range adaptor, and I think we would lose `it.index()`?
>>
>> Yep, something along those lines - yep, would lose a nice spelling for `index` on the iterator (it'd just be a tuple) - but given structured bindings, do people much want/need that naming anyway?
>
> I see. I think in this specific case the ergonomics make this work in real world. We have a considerable amount of code in MLIR and IREE that iterates over multidimensional stuff in lockstep, and it's nice to have a concise and safe way to manage that. I don't think that `flatten` achieves that given the total amount of nesting.

The total amount of nesting in the call? 3, in this case - flatten+enumerate+zip - I wouldn't be against having a wrapper, I guess, that does those things together - while still having tehm implemented as independent features, rather than having enumerate or zip being aware of each other.

> Instead, one could unpack the values in the first statement inside the loop like so:
>
>   for (auto [Idx, Val] : enumerate(zip_equal(...))) {
>     auto [X, Y, Z] = Val.value()

That seems fine too as a solution to the issue, rather than introducing this enumerate+zip special case?

> Another issue I see is unintentionally unpacking a single element in generic code -- a single range can contain tuple values, and I don't think we can tell this apart from `zip(...)` without checking the range/iterator type.

Not sure I follow - the generic code would be using `flatten(enumerate(zip...))` so it'd still always be flattening the enumerate+zip, if the generic code were calling flatten+enumerate, without knowing the contents of the enumerate - it'd be asking to flatten whatever was being enumerated. I don't follow there being an unintentional ambiguity between the two.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144503/new/

https://reviews.llvm.org/D144503



More information about the llvm-commits mailing list