From: Francis Ricci Date: Fri, 9 Jun 2017 20:31:53 +0000 (+0000) Subject: [ADT] Make iterable SmallVector template overrides more specific X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=180505542004ed2cb6624c50b3dddf1790e93dd5;p=llvm [ADT] Make iterable SmallVector template overrides more specific Summary: This prevents the iterator overrides from being selected in the case where non-iterator types are used as arguments, which is of particular importance in cases where other overrides with identical types exist. Reviewers: dblaikie, bkramer, rafael Subscribers: llvm-commits, efriedma Differential Revision: https://reviews.llvm.org/D33919 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305105 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 35c25500200..bf2a62f43af 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -388,7 +388,10 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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); } diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index e1a2b702a8a..5903ce8c08e 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -209,6 +209,22 @@ typedef ::testing::Types, > 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 @@ TYPED_TEST(SmallVectorTest, AppendRepeatedTest) { 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 @@ TYPED_TEST(SmallVectorTest, AssignRangeTest) { 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 @@ TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { 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");