diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-07-31 09:42:24 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-07-31 09:42:24 +0000 |
commit | 06bd8ca8c276d9bc20b192188224e1e5215666a0 (patch) | |
tree | ce0e4cc9bad21a7beb0ecbfed45245ced370bd8f /include/llvm/ADT/TinyPtrVector.h | |
parent | 3f5054f922fe0164e14750845f84d3e0e00ab7a1 (diff) | |
download | llvm-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.h | 65 |
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 |