<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Dec 5, 2020, at 10:46 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="">dblaikie@gmail.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class=""><div class=""><div class="">I think I see what you’re going for here, and I agree that std::string is a slightly different situation than std::vector given that some implementations have a small string optimizations already.</div><div class=""><br class=""></div><div class="">I feel like you’re prioritizing the iterator invalidation behavior as the core difference between the two types, whereas I’m prioritizing the performance/allocation-behavior aspect. I feel like this is a major difference in practice that API users should think about, and they should be prepared to deal with the iterator invalidation issues as necessary.</div><div class=""><br class=""></div><div class="">Is the "Reduced sizeof(t) and guaranteed iterator validity over swap/move (ie: must not use an inline buffer)” use case important enough to have a “string-y” type?</div></div></div></blockquote><div class=""><br class=""></div><div class="">I think things got confused again - reduced sizeof/guaranteed iterator validity isn't a string-y type (because of the iterator validity guarantee such a type can't use an inline buffer - unlike std::string), it's what we're talking about/potentially calling llvm::Vector.</div></div></div></div></blockquote><div><br class=""></div>Ok, I thought you were talking about bringing that idea to string-y types because std::string doesn’t provide it..</div><div> <br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class=""><div class=""><div class=""> As you say, we don’t have a solution for this in the current code other than std::vector. I haven’t heard of this being a significant enough problem to be worth “fixing”, and I don’t think we can drop the inline vs out-of-line distinction.</div></div></div></blockquote><div class=""><br class="">Hmm - I think I'm still miscommunicating/not making sense.<br class=""><br class="">I think there's value in having a type that has a guarantee of no-inline-storage - when you want to move and maintain iterator validity.<br class=""></div></div></div></blockquote><div><br class=""></div><div>Right, in the vector domain, this is the llvm::Vector type(def).</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_quote"><div class="">But I'm wondering if the type with possibly using inline storage could be thought of more like std::string (ie: define the contract: iterators invalidated on move) rather than like SmallVector (ie: "must have an inline buffer"). I don't know what we would call this thing - but my point is to try to move away from the name dictating the implementation detail of having an inline buffer (we could still have SmallVector<T, N> for when you specifically want an inline buffer) but OtherThingVector<T> would not require an inline buffer it would be "a type without iterator validity on move that has, or doesn't have, an inline buffer as it chooses to based on performance tradeoffs".<br class=""><br class="">I think, to me, this would be better than "SmallVector<T> must have at least 1 inline element because of the word "Small" in the name" if we moved away from having Small in the name, and towards some sense of the contract & leaving the implementation to make the choice of how to best implement that contract.<br class=""><br class="">But I think I'm going around in circles/not necessarily making sense here. Perhaps a chat on discord or something would be more effective?</div></div></div></blockquote><div><br class=""></div><div>I think I understand what you’re saying: you’re focusing on making iterator invalidation semantics primary instead of memory layout. This is a reasonable thing to do, but I don’t think we should go with a design that ignores the “in place ness”. Maybe there is a “best of both worlds” design proposal that could make sense here?</div><div><br class=""></div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class=""><div class=""><div class="">The difference I meant was that it forwards transparently to array_pod_sort / qsort which is a pretty big behavioral difference.<br class=""></div></div></div></blockquote><div class=""><br class="">Ah, more llvm::sort(iter, iter) - yeah, hadn't thought about that one. Different performance characteristics, but the same contract, right? So this is working around sub-optimal standard library implementations, but not providing a different contract/requirements, is it?<br class=""></div></div></div></blockquote><div><br class=""></div><div>It’s really a “similar but different” API. I works the same in the easy cases, but doesn’t have the same set of contracts, that was my only analogy. There are lots of other APIs that are similar-but-different in innumerable ways that provide tradeoffs e.g. DenseMap vs std::map, etc. The programmer’s manual has a long list of options :-)</div><div><br class=""></div><div>-Chris</div><br class=""></div><br class=""></body></html>