This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Add an early-increment iterator and range adaptor.
ClosedPublic

Authored by chandlerc on Jul 28 2018, 2:55 AM.

Details

Summary

This allows us to model the common LLVM idiom of incrementing
immediately after dereferencing so that we can remove or update the
entity w/o losing our ability to reach the "next".

Diff Detail

Repository
rL LLVM

Event Timeline

chandlerc created this revision.Jul 28 2018, 2:55 AM
chandlerc updated this revision to Diff 157876.Jul 28 2018, 4:26 PM

Update with actual documentation (instead of it being missing or talking about
the wrong thing) and a more direct implementation strategy.

Initially, I tried to make this behave more like a normal forward iterator.
Unfortunately, that makes it substantially less powerful than the
early-increment patterned loops we use throughout LLVM because it precludes the
current iterator from becoming invalid -- we compare against it when
incrementing.

Instead, this now directly models the early-increment loops in LLVM. It makes
it a weird quasi-iterator-like thing, despite claiming to be an InputIterator.
I'm not sure if people will be happy with this but it seems functional and to
work quite nicely with the way LLVM would want to use it.

chandlerc updated this revision to Diff 157878.Jul 28 2018, 5:16 PM

Now with correct usage of the ABI breaking checks macro and fixing a silly
compile error.

Yeah, that's vaguely frightening as a thing (I mean, yeah, the assertions help catch misuse - but still).

Got a pointer to an example of where you want to do this? Any chance of inverting this into a lambda-driven algorithm instead, maybe?

pre_inc_for(R, [&](const auto &V) {
  ...
});

We have many, many for loops still using iterators for this....

If you search for thinsg like Foo &Var = *It++; with different
identifiers you will find a bunch.

I think we would be unsuccessful at converting them to lambda accepting
algorithms. The range based for loop seems likely the most we would succeed
in threading through how people think about this.... I mean, if there is no
consensus for this iterator-like thing, then maybe we have to go w/
algorithms. My fear is that it means we will just go with iterator for
loops.

dblaikie accepted this revision.Aug 1 2018, 11:59 AM

Fair enough. An algorithm has issues with break/continue (well, continue can be easily transformed to 'return', though that can hinder readability, especially for long loop bodies where it's not immediately obvious that the return is from a lambda, rather than from the function as a whole) that this won't. Hopefully the assertions are enough to catch any particularly weird usage.

This revision is now accepted and ready to land.Aug 1 2018, 11:59 AM
This revision was automatically updated to reflect the committed changes.