From a7a33fd95f15428b7030ef1b764fcf924d5199c8 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99633 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallVector.h | 24 ++++++++++++++++++------ unittests/ADT/SmallVectorTest.cpp | 6 ++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index c2afb7e681d..2d79a029d01 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/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/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index d7dc3af52fe..991c7d6caac 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/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()); +} + }