<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 7, 2015, at 3:18 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="">dblaikie@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">(+Chandler because I've talked to him a few times about range adapters and he's expressed hesitancy, I believe hoping to wait for some direction to come out of the C++ standards committee, but that was quite a while back - not sure what the state is now)<br class=""></div></div></blockquote>I’m happy to wait on seeing what the committee does.  Although with things like unique_ptr we were willing to have our own in LLVM until we moved to C++11.  I’d be happy to see us do the same with range adapters.<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Apr 7, 2015 at 3:02 PM, Pete Cooper <span dir="ltr" class=""><<a href="mailto:peter_cooper@apple.com" target="_blank" class="">peter_cooper@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all<br class="">
<br class="">
This patch adds a wrapper to iterators to allow us to use foreach loops, but also get the index of elements.  This allows a greater number of loops to use foreach, or avoid a foreach with a separate index.<br class=""></blockquote><div class=""><br class="">Usual caveat for range adapters (not a problem for /iterator/ adapters) is lifetime:<br class=""><br class="">container func();<br class=""><br class="">for (auto x : func()) // this is fine<br class="">  f(x);<br class=""><br class="">for (auto x : wrap(func()) // this will invoke UB</div><div class="">  f(x)<br class=""><br class="">the problem being that range-for uses reference-extension to extend the lifetime of the container, but if it's wrapped then only the lifetime of the wrapper will be extended. <br class=""><br class="">This is the main thing holding up standardization of range adapters in C++, as I understand it (though I haven't followed closely).<br class=""><br class="">Options include<br class=""><br class="">1) disallow: add an overload of IndexedIterator that takes the container by rvalue reference, and = delete it<br class="">2) do nothing (the range adapter would still work for temporaries when passed to another function that does the work, rather than to a range-for loop or other reference-extension context: do_things(reverse(createSequence())); for example)<br class="">3) get really fancy and have range adapter that takes rvalue reference objects and moves them into the adapter itself to extend their lifetime - there's all sorts of interesting gotchas here, especially once you get around to composability of range adapters… <br class=""></div></div></div></div></div></blockquote>Ouch!  Thanks for the breakdown of the options here.  I can see why its UB, but i’d never have thought of this myself.  Its clear that what i’ve written is about the minimum required to get something to work, but not necessarily complete.<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
I’ve updated a loop in AArch64A57FPLoadBalancing to show this.  The gist of the change is that the loop goes from<br class="">
<br class="">
  unsigned Idx = 0;<br class="">
  for (auto &MI : MBB)<br class="">
    scanInstruction(&MI, Idx++, ActiveChains, AllChains);<br class="">
<br class="">
to<br class="">
<br class="">
  for (auto MI : IndexedIterator(MBB))<br class="">
    scanInstruction(&*MI, MI.index(), ActiveChains, AllChains);<br class="">
<br class="">
So accesses to the iterator need a *, and there’s a new index() method.  I considered adding a .value() to the iterator instead of *.  I’m not strongly attached to one over the other (or both).<br class=""></blockquote><div class=""><br class="">Yeah, I'd probably make it a trivial struct with a "index" and "value" member (the value member would be a const ref - though this makes the "auto" versus "auto&" in the range-for a bit misleading... <br class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Comments welcome.  I personally like the idea wrapping iterators, but i understand if anyone is fundamentally opposed.  I’d really like to add another wrapper later which keeps track of the next pointer for you as then the current element can be safely deleted.<br class=""></blockquote><div class=""><br class="">Yeah, there's a bunch of range adapters that would be handy. Lang & I were talking about the desire for a "reverse" adapter. <br class=""></div></div></div></div></div></blockquote>Yeah, reverse would be extremely useful.  As would iterating over 2 containers in parallel.  I think Lang said thats like Haskell’s zip.</div><div><br class=""></div><div>Anyway, i’m happy to put this patch aside for now and wait to see what comes out the standards committee.  Thanks agains for the feedback.</div><div><br class=""></div><div>Cheers,</div><div>Pete<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
Cheers,<br class="">
Pete<br class="">
<br class="">
<br class=""><br class="">
<br class="">
<br class="">
<br class="">_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>