<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 20, 2016 at 5:55 PM, Duncan P. N. Exon Smith via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class="gmail-"><blockquote type="cite"><div>On 2016-Dec-20, at 15:44, Kyle Butt <<a href="mailto:iteratee@google.com" target="_blank">iteratee@google.com</a>> wrote:</div><br class="gmail-m_7476458174440795564Apple-interchange-newline"><div><div dir="ltr"><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">Normally, reverse iterators are not off-by-one.  See the reverse iterators provided by containers like std::set, std::map, std::list, etc..  All of these have a handle to the same node that is getting dereferenced.  They work by having a sentinel, rend(), that's past the final (reverse) element.  They have similar guarantees to the forward iterators: they are only invalidated when the pointed-to-node gets deleted.</blockquote><div><br></div><div>This isn't true. std::set, std::map, std::list also do the off by one accounting.<br></div></div></div></blockquote><div><br></div></span><div>Huh... I stand corrected.  Not sure how I got that :/.  Regretfully, I had this incorrect impression when I was working on this, and probably convinced others of it.</div><div><br></div><div>I stand by my point that the new invalidation semantics are strictly better.  But being inconsistent is awkward...</div><span class="gmail-"><br><blockquote type="cite"><div><div dir="ltr"><div><div class="gmail_extra"><div class="gmail_quote"><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
I haven't looked at this patch; from the limited context here, I don't understand why you'd *want* off-by-one accounting.  Off-by-one accounting is usually complicated and hard to reason about...<br>
<div class="gmail-m_7476458174440795564gmail-HOEnZb"><div class="gmail-m_7476458174440795564gmail-h5"><br></div></div></blockquote><div><br></div><div>When dealing with a range, off by one makes perfect sense. When you need to shrink from the front, you work from [begin, end)</div><div>Then to start working from the back you flip the iterators and now you have (rend, rbegin]</div></div></div></div></div></div></blockquote><div><br></div></span><div>It's the invalidation that's hard to reason about.</div><div><div class="gmail-h5"><br></div></div></div></div></blockquote><div><br></div><div>I think you're referring to this invalidation behavior?</div><div><br></div><div><a href="http://stackoverflow.com/questions/19826255/why-does-insert-invalidate-the-stdset-reverse-iterator">http://stackoverflow.com/questions/19826255/why-does-insert-invalidate-the-stdset-reverse-iterator</a></div><div><br></div><div>If you have to make reverse_iterator a wrapper, you have to do this.</div><div><br></div></div>There's a middle ground where end().reverse() will give you rbegin(), but has the invalidation semantics that you want.</div><div class="gmail_extra">I think that is actually the optimal situation.</div><div class="gmail_extra"><br></div><div class="gmail_extra">In either case, I think that this discussion shouldn't impede the patch.</div></div>