Index: llvm/trunk/include/llvm/ADT/SmallVector.h =================================================================== --- llvm/trunk/include/llvm/ADT/SmallVector.h +++ llvm/trunk/include/llvm/ADT/SmallVector.h @@ -388,7 +388,10 @@ void swap(SmallVectorImpl &RHS); /// Add the specified range to the end of the SmallVector. - template + template ::iterator_category, + std::input_iterator_tag>::value>::type> void append(in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); // Grow allocated space if needed. @@ -426,7 +429,11 @@ std::uninitialized_fill(this->begin(), this->end(), Elt); } - template void assign(in_iter in_start, in_iter in_end) { + template ::iterator_category, + std::input_iterator_tag>::value>::type> + void assign(in_iter in_start, in_iter in_end) { clear(); append(in_start, in_end); } @@ -579,7 +586,10 @@ return I; } - template + template ::iterator_category, + std::input_iterator_tag>::value>::type> iterator insert(iterator I, ItTy From, ItTy To) { // Convert iterator to elt# to avoid invalidating iterator when we reserve() size_t InsertElt = I - this->begin(); @@ -860,7 +870,10 @@ this->assign(Size, Value); } - template + template ::iterator_category, + std::input_iterator_tag>::value>::type> SmallVector(ItTy S, ItTy E) : SmallVectorImpl(N) { this->append(S, E); } Index: llvm/trunk/unittests/ADT/SmallVectorTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/SmallVectorTest.cpp +++ llvm/trunk/unittests/ADT/SmallVectorTest.cpp @@ -209,6 +209,22 @@ > SmallVectorTestTypes; TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes); +// Constructor test. +TYPED_TEST(SmallVectorTest, ConstructorNonIterTest) { + SCOPED_TRACE("ConstructorTest"); + this->theVector = SmallVector(2, 2); + this->assertValuesInOrder(this->theVector, 2u, 2, 2); +} + +// Constructor test. +TYPED_TEST(SmallVectorTest, ConstructorIterTest) { + SCOPED_TRACE("ConstructorTest"); + int arr[] = {1, 2, 3}; + this->theVector = + SmallVector(std::begin(arr), std::end(arr)); + this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); +} + // New vector test. TYPED_TEST(SmallVectorTest, EmptyVectorTest) { SCOPED_TRACE("EmptyVectorTest"); @@ -415,6 +431,33 @@ this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77); } +// Append test +TYPED_TEST(SmallVectorTest, AppendNonIterTest) { + SCOPED_TRACE("AppendRepeatedTest"); + + this->theVector.push_back(Constructable(1)); + this->theVector.append(2, 7); + this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); +} + +TYPED_TEST(SmallVectorTest, AppendRepeatedNonForwardIterator) { + SCOPED_TRACE("AppendRepeatedTest"); + + struct output_iterator { + typedef std::output_iterator_tag iterator_category; + typedef int value_type; + typedef int difference_type; + typedef value_type *pointer; + typedef value_type &reference; + operator int() { return 2; } + operator Constructable() { return 7; } + }; + + this->theVector.push_back(Constructable(1)); + this->theVector.append(output_iterator(), output_iterator()); + this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); +} + // Assign test TYPED_TEST(SmallVectorTest, AssignTest) { SCOPED_TRACE("AssignTest"); @@ -434,6 +477,15 @@ this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); } +// Assign test +TYPED_TEST(SmallVectorTest, AssignNonIterTest) { + SCOPED_TRACE("AssignTest"); + + this->theVector.push_back(Constructable(1)); + this->theVector.assign(2, 7); + this->assertValuesInOrder(this->theVector, 2u, 7, 7); +} + // Move-assign test TYPED_TEST(SmallVectorTest, MoveAssignTest) { SCOPED_TRACE("MoveAssignTest"); @@ -532,6 +584,15 @@ this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4); } +TYPED_TEST(SmallVectorTest, InsertRepeatedNonIterTest) { + SCOPED_TRACE("InsertRepeatedTest"); + + this->makeSequence(this->theVector, 1, 4); + Constructable::reset(); + auto I = this->theVector.insert(this->theVector.begin() + 1, 2, 7); + EXPECT_EQ(this->theVector.begin() + 1, I); + this->assertValuesInOrder(this->theVector, 6u, 1, 7, 7, 2, 3, 4); +} TYPED_TEST(SmallVectorTest, InsertRepeatedAtEndTest) { SCOPED_TRACE("InsertRepeatedTest");