summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-08-01 08:40:48 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-08-01 08:40:48 +0000
commit147d9e05116518461653695a6022f6109f0eb936 (patch)
tree9ef3b39a476abc17691e7270cd7709a6defa4e46
parent0b1bcbf6b87f19402d8aef1ef9f6e527a07de9d4 (diff)
downloadllvm-147d9e05116518461653695a6022f6109f0eb936.tar.gz
llvm-147d9e05116518461653695a6022f6109f0eb936.tar.bz2
llvm-147d9e05116518461653695a6022f6109f0eb936.tar.xz
Add range erase, element insert, and range insert methods to
TinyPtrVector. With these, it is sufficiently functional for my more normal / pedestrian uses. I've not included some r-value reference stuff here because the value type for a TinyPtrVector is, necessarily, just a pointer. I've added tests that cover the basic behavior of these routines, but they aren't as comprehensive as I'd like. In particular, they don't really test the iterator semantics as thoroughly as they should. Maybe some brave soul will feel enterprising and flesh them out. ;] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161104 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/TinyPtrVector.h58
-rw-r--r--unittests/ADT/TinyPtrVectorTest.cpp91
2 files changed, 148 insertions, 1 deletions
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index d226bc2085..d3d33b8add 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -11,8 +11,9 @@
#define LLVM_ADT_TINYPTRVECTOR_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -229,6 +230,61 @@ public:
}
return end();
}
+
+ iterator erase(iterator S, iterator E) {
+ assert(S >= begin() && "Range to erase is out of bounds.");
+ assert(S <= E && "Trying to erase invalid range.");
+ assert(E <= end() && "Trying to erase past the end.");
+
+ if (Val.template is<EltTy>()) {
+ if (S == begin() && S != E)
+ Val = (EltTy)0;
+ } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+ return Vec->erase(S, E);
+ }
+ return end();
+ }
+
+ iterator insert(iterator I, const EltTy &Elt) {
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+ if (I == end()) {
+ push_back(Elt);
+ return llvm::prior(end());
+ }
+ assert(!Val.isNull() && "Null value with non-end insert iterator.");
+ if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ assert(I == begin());
+ Val = Elt;
+ push_back(V);
+ return begin();
+ }
+
+ return Val.template get<VecTy*>()->insert(I, Elt);
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+ assert(I <= this->end() && "Inserting past the end of the vector.");
+ if (From == To)
+ return I;
+
+ // If we have a single value, convert to a vector.
+ ptrdiff_t Offset = I - begin();
+ if (Val.isNull()) {
+ if (llvm::next(From) == To) {
+ Val = *From;
+ return begin();
+ }
+
+ Val = new VecTy();
+ } else if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ Val = new VecTy();
+ Val.template get<VecTy*>()->push_back(V);
+ }
+ return Val.template get<VecTy*>()->insert(begin() + Offset, From, To);
+ }
};
} // end namespace llvm
diff --git a/unittests/ADT/TinyPtrVectorTest.cpp b/unittests/ADT/TinyPtrVectorTest.cpp
index 94939279c1..05dd797e01 100644
--- a/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/unittests/ADT/TinyPtrVectorTest.cpp
@@ -354,4 +354,95 @@ TYPED_TEST(TinyPtrVectorTest, EraseTest) {
this->expectValues(this->V, this->testArray(0));
}
+TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) {
+ this->appendValues(this->V, this->testArray(1));
+ this->expectValues(this->V, this->testArray(1));
+ this->V.erase(this->V.begin(), this->V.begin());
+ this->expectValues(this->V, this->testArray(1));
+ this->V.erase(this->V.end(), this->V.end());
+ this->expectValues(this->V, this->testArray(1));
+ this->V.erase(this->V.begin(), this->V.end());
+ this->expectValues(this->V, this->testArray(0));
+
+ this->appendValues(this->V, this->testArray(42));
+ this->expectValues(this->V, this->testArray(42));
+ this->V.erase(this->V.begin(), llvm::next(this->V.begin(), 1));
+ this->TestPtrs.erase(this->TestPtrs.begin(),
+ llvm::next(this->TestPtrs.begin(), 1));
+ this->expectValues(this->V, this->testArray(41));
+ this->V.erase(llvm::next(this->V.begin(), 1), llvm::next(this->V.begin(), 2));
+ this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1),
+ llvm::next(this->TestPtrs.begin(), 2));
+ this->expectValues(this->V, this->testArray(40));
+ this->V.erase(llvm::next(this->V.begin(), 2), llvm::next(this->V.begin(), 4));
+ this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2),
+ llvm::next(this->TestPtrs.begin(), 4));
+ this->expectValues(this->V, this->testArray(38));
+ this->V.erase(llvm::next(this->V.begin(), 5), llvm::next(this->V.begin(), 10));
+ this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5),
+ llvm::next(this->TestPtrs.begin(), 10));
+ this->expectValues(this->V, this->testArray(33));
+ this->V.erase(llvm::next(this->V.begin(), 13), llvm::next(this->V.begin(), 26));
+ this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13),
+ llvm::next(this->TestPtrs.begin(), 26));
+ this->expectValues(this->V, this->testArray(20));
+ this->V.erase(llvm::next(this->V.begin(), 7), this->V.end());
+ this->expectValues(this->V, this->testArray(7));
+ this->V.erase(this->V.begin(), this->V.end());
+ this->expectValues(this->V, this->testArray(0));
+}
+
+TYPED_TEST(TinyPtrVectorTest, Insert) {
+ this->V.insert(this->V.end(), this->TestPtrs[0]);
+ this->expectValues(this->V, this->testArray(1));
+ this->V.clear();
+ this->appendValues(this->V, this->testArray(4));
+ this->expectValues(this->V, this->testArray(4));
+ this->V.insert(this->V.end(), this->TestPtrs[4]);
+ this->expectValues(this->V, this->testArray(5));
+ this->V.insert(this->V.begin(), this->TestPtrs[42]);
+ this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]);
+ this->expectValues(this->V, this->testArray(6));
+ this->V.insert(llvm::next(this->V.begin(), 3), this->TestPtrs[43]);
+ this->TestPtrs.insert(llvm::next(this->TestPtrs.begin(), 3),
+ this->TestPtrs[43]);
+ this->expectValues(this->V, this->testArray(7));
+}
+
+TYPED_TEST(TinyPtrVectorTest, InsertRange) {
+ this->V.insert(this->V.end(), this->TestPtrs.begin(), this->TestPtrs.begin());
+ this->expectValues(this->V, this->testArray(0));
+ this->V.insert(this->V.begin(), this->TestPtrs.begin(),
+ this->TestPtrs.begin());
+ this->expectValues(this->V, this->testArray(0));
+ this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end());
+ this->expectValues(this->V, this->testArray(0));
+ this->V.insert(this->V.end(), this->TestPtrs.begin(),
+ llvm::next(this->TestPtrs.begin()));
+ this->expectValues(this->V, this->testArray(1));
+ this->V.clear();
+ this->V.insert(this->V.end(), this->TestPtrs.begin(),
+ llvm::next(this->TestPtrs.begin(), 2));
+ this->expectValues(this->V, this->testArray(2));
+ this->V.clear();
+ this->V.insert(this->V.end(), this->TestPtrs.begin(),
+ llvm::next(this->TestPtrs.begin(), 42));
+ this->expectValues(this->V, this->testArray(42));
+ this->V.clear();
+ this->V.insert(this->V.end(),
+ llvm::next(this->TestPtrs.begin(), 5),
+ llvm::next(this->TestPtrs.begin(), 13));
+ this->V.insert(this->V.begin(),
+ llvm::next(this->TestPtrs.begin(), 0),
+ llvm::next(this->TestPtrs.begin(), 3));
+ this->V.insert(llvm::next(this->V.begin(), 2),
+ llvm::next(this->TestPtrs.begin(), 2),
+ llvm::next(this->TestPtrs.begin(), 4));
+ this->V.erase(llvm::next(this->V.begin(), 4));
+ this->V.insert(llvm::next(this->V.begin(), 4),
+ llvm::next(this->TestPtrs.begin(), 4),
+ llvm::next(this->TestPtrs.begin(), 5));
+ this->expectValues(this->V, this->testArray(13));
+}
+
}