forked from OSchip/llvm-project
[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 llvm-svn: 305105
This commit is contained in:
parent
f21b803876
commit
e22b696936
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue