[llvm-commits] [llvm] r134554 - in /llvm/trunk: include/llvm/ADT/SmallVector.h unittests/ADT/SmallVectorTest.cpp

Duncan P. N. Exon Smith dexonsmith at apple.com
Wed Dec 3 10:10:49 PST 2014


> On 2014-Dec-02, at 21:48, David Blaikie <dblaikie at gmail.com> wrote:
> 
> Right - and it's not strictly optimal - if the grow operation was split (allocating the new buffer first, then constructing the newly-inserted element, then moving elements over) it could be done without extra moves. But that's more work.
> 
> I think my head got sore right about the time I tried to figure out what, if any, guarantees could be given for insertion of a range into itself... when there's no reallocation happening, it's impossible (because you have to move things out of the way first - so you might've broken the range - indeed even a non-range insertion, if the referenced element comes after the insertion point... I can't remember if libc++ (I looked around in there to see how to implement these things, which things were required and which weren't) did some sorcery to handle some subset of those cases - perhaps by building the new element at the end, then swapping it in? I forget)

FWIW, STL sequences don't allow self-referencing range insertion.  From
n3337, section 23.2.3, Table 100:
 
> a.insert(p,i,j)
> 
> iterator
> 
> Requires:T shall be EmplaceConstructible into X from *i. For vector, if the iterator does not meet the forward iterator requirements (24.2.5), T shall also be MoveInsertable into X and MoveAssignable. Each iterator in the range [i,j) shall be dereferenced exactly once.
> 
> pre: i and j are not iterators into a.
> Inserts copies of elements in [i, j) before p

I imagine the rest of it is all fixable, through various sorts of
sorcery, as you mentioned.  The only barrier is running benchmarks to
be sure we don't have any major compile-time regressions.



More information about the llvm-commits mailing list