summaryrefslogtreecommitdiff
path: root/include/llvm/ADT/TinyPtrVector.h
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-07-31 09:42:24 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-07-31 09:42:24 +0000
commit06bd8ca8c276d9bc20b192188224e1e5215666a0 (patch)
treece0e4cc9bad21a7beb0ecbfed45245ced370bd8f /include/llvm/ADT/TinyPtrVector.h
parent3f5054f922fe0164e14750845f84d3e0e00ab7a1 (diff)
downloadllvm-06bd8ca8c276d9bc20b192188224e1e5215666a0.tar.gz
llvm-06bd8ca8c276d9bc20b192188224e1e5215666a0.tar.bz2
llvm-06bd8ca8c276d9bc20b192188224e1e5215666a0.tar.xz
Implement copy and move assignment for TinyPtrVector. These try to
re-use allocated vectors as much as possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161041 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT/TinyPtrVector.h')
-rw-r--r--include/llvm/ADT/TinyPtrVector.h65
1 files changed, 56 insertions, 9 deletions
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index a02c10edf7..1038c78448 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -32,19 +32,72 @@ public:
llvm::PointerUnion<EltTy, VecTy*> Val;
TinyPtrVector() {}
+ ~TinyPtrVector() {
+ if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ delete V;
+ }
+
TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
if (VecTy *V = Val.template dyn_cast<VecTy*>())
Val = new VecTy(*V);
}
+ TinyPtrVector &operator=(const TinyPtrVector &RHS) {
+ if (this == &RHS)
+ return *this;
+ if (RHS.empty()) {
+ this->clear();
+ return *this;
+ }
+
+ // Try to squeeze into the single slot. If it won't fit, allocate a copied
+ // vector.
+ if (Val.template is<EltTy>()) {
+ if (RHS.size() == 1)
+ Val = RHS.front();
+ else
+ Val = new VecTy(*RHS.Val.template get<VecTy*>());
+ return *this;
+ }
+
+ // If we have a full vector allocated, try to re-use it.
+ if (RHS.Val.template is<EltTy>()) {
+ Val.template get<VecTy*>()->clear();
+ Val.template get<VecTy*>()->push_back(RHS.front());
+ } else {
+ *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>();
+ }
+ return *this;
+ }
+
#if LLVM_USE_RVALUE_REFERENCES
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
RHS.Val = (EltTy)0;
}
-#endif
- ~TinyPtrVector() {
- if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ TinyPtrVector &operator=(TinyPtrVector &&RHS) {
+ if (this == &RHS)
+ return *this;
+ if (RHS.empty()) {
+ this->clear();
+ return *this;
+ }
+
+ // If this vector has been allocated on the heap, re-use it if cheap. If it
+ // would require more copying, just delete it and we'll steal the other
+ // side.
+ if (VecTy *V = Val.template dyn_cast<VecTy*>()) {
+ if (RHS.Val.template is<EltTy>()) {
+ V->clear();
+ V->push_back(RHS.front());
+ return *this;
+ }
delete V;
+ }
+
+ Val = RHS.Val;
+ RHS.Val = (EltTy)0;
+ return *this;
}
+#endif
// implicit conversion operator to ArrayRef.
operator ArrayRef<EltTy>() const {
@@ -173,12 +226,6 @@ public:
}
return end();
}
-
-private:
- void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
-#if LLVM_USE_RVALUE_REFERENCES
- void operator=(TinyPtrVector&&); // NOT IMPLEMENTED YET.
-#endif
};
} // end namespace llvm