summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ADT/SmallVector.h21
-rw-r--r--llvm/unittests/ADT/SmallVectorTest.cpp61
2 files changed, 78 insertions, 4 deletions
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 35c25500200..bf2a62f43af 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/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<typename in_iter>
+ template <typename in_iter,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<in_iter>::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 <typename in_iter> void assign(in_iter in_start, in_iter in_end) {
+ template <typename in_iter,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<in_iter>::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<typename ItTy>
+ template <typename ItTy,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<ItTy>::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<typename ItTy>
+ template <typename ItTy,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<ItTy>::iterator_category,
+ std::input_iterator_tag>::value>::type>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
this->append(S, E);
}
diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
index e1a2b702a8a..5903ce8c08e 100644
--- a/llvm/unittests/ADT/SmallVectorTest.cpp
+++ b/llvm/unittests/ADT/SmallVectorTest.cpp
@@ -209,6 +209,22 @@ typedef ::testing::Types<SmallVector<Constructable, 0>,
> SmallVectorTestTypes;
TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes);
+// Constructor test.
+TYPED_TEST(SmallVectorTest, ConstructorNonIterTest) {
+ SCOPED_TRACE("ConstructorTest");
+ this->theVector = SmallVector<Constructable, 2>(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<Constructable, 4>(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");
OpenPOWER on IntegriCloud