From 42e77df78ca18f7f645a15530f44b3244b6b0781 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 26 Mar 2010 18:53:37 +0000 Subject: [PATCH] Fix SmallVector's insert to handle non-random-access iterators. llvm-svn: 99633 --- llvm/include/llvm/ADT/SmallVector.h | 24 ++++++++++++++++++------ llvm/unittests/ADT/SmallVectorTest.cpp | 6 ++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h index c2afb7e681d1..2d79a029d019 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -239,11 +239,20 @@ public: /// starting with "Dest", constructing elements into it as needed. template static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - // Use memcpy for PODs: std::uninitialized_copy optimizes to memmove, memcpy - // is better. - memcpy(&*Dest, &*I, (E-I)*sizeof(T)); + // Arbitrary iterator types; just use the basic implementation. + std::uninitialized_copy(I, E, Dest); } - + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) { + // Use memcpy for PODs iterated by pointers (which includes SmallVector + // iterators): std::uninitialized_copy optimizes to memmove, but we can + // use memcpy here. + memcpy(Dest, I, (E-I)*sizeof(T)); + } + /// grow - double the size of the allocated memory, guaranteeing space for at /// least one more element or MinSize if specified. void grow(size_t MinSize = 0) { @@ -501,10 +510,13 @@ public: this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); // Replace the overwritten part. - std::copy(From, From+NumOverwritten, I); + for (; NumOverwritten > 0; --NumOverwritten) { + *I = *From; + ++I; ++From; + } // Insert the non-overwritten middle part. - this->uninitialized_copy(From+NumOverwritten, To, OldEnd); + this->uninitialized_copy(From, To, OldEnd); return I; } diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp index d7dc3af52feb..991c7d6caac7 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -14,6 +14,7 @@ #include "gtest/gtest.h" #include "llvm/ADT/SmallVector.h" #include +#include using namespace llvm; @@ -399,4 +400,9 @@ TEST_F(SmallVectorTest, DirectVectorTest) { EXPECT_EQ(4, theVector[3].getValue()); } +TEST_F(SmallVectorTest, IteratorTest) { + std::list L; + theVector.insert(theVector.end(), L.begin(), L.end()); +} + }