Home | History | Annotate | Download | only in ADT
      1 //===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_ADT_TINYPTRVECTOR_H
     11 #define LLVM_ADT_TINYPTRVECTOR_H
     12 
     13 #include "llvm/ADT/SmallVector.h"
     14 #include "llvm/ADT/PointerUnion.h"
     15 
     16 namespace llvm {
     17 
     18 /// TinyPtrVector - This class is specialized for cases where there are
     19 /// normally 0 or 1 element in a vector, but is general enough to go beyond that
     20 /// when required.
     21 ///
     22 /// NOTE: This container doesn't allow you to store a null pointer into it.
     23 ///
     24 template <typename EltTy>
     25 class TinyPtrVector {
     26 public:
     27   typedef llvm::SmallVector<EltTy, 4> VecTy;
     28   llvm::PointerUnion<EltTy, VecTy*> Val;
     29 
     30   TinyPtrVector() {}
     31   TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
     32     if (VecTy *V = Val.template dyn_cast<VecTy*>())
     33       Val = new VecTy(*V);
     34   }
     35   ~TinyPtrVector() {
     36     if (VecTy *V = Val.template dyn_cast<VecTy*>())
     37       delete V;
     38   }
     39 
     40   bool empty() const {
     41     // This vector can be empty if it contains no element, or if it
     42     // contains a pointer to an empty vector.
     43     if (Val.isNull()) return true;
     44     if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
     45       return Vec->empty();
     46     return false;
     47   }
     48 
     49   unsigned size() const {
     50     if (empty())
     51       return 0;
     52     if (Val.template is<EltTy>())
     53       return 1;
     54     return Val.template get<VecTy*>()->size();
     55   }
     56 
     57   typedef const EltTy *iterator;
     58   iterator begin() const {
     59     if (empty())
     60       return 0;
     61 
     62     if (Val.template is<EltTy>())
     63       return Val.template getAddrOf<EltTy>();
     64 
     65     return Val.template get<VecTy *>()->begin();
     66 
     67   }
     68   iterator end() const {
     69     if (empty())
     70       return 0;
     71 
     72     if (Val.template is<EltTy>())
     73       return begin() + 1;
     74 
     75     return Val.template get<VecTy *>()->end();
     76   }
     77 
     78 
     79   EltTy operator[](unsigned i) const {
     80     assert(!Val.isNull() && "can't index into an empty vector");
     81     if (EltTy V = Val.template dyn_cast<EltTy>()) {
     82       assert(i == 0 && "tinyvector index out of range");
     83       return V;
     84     }
     85 
     86     assert(i < Val.template get<VecTy*>()->size() &&
     87            "tinyvector index out of range");
     88     return (*Val.template get<VecTy*>())[i];
     89   }
     90 
     91   EltTy front() const {
     92     assert(!empty() && "vector empty");
     93     if (EltTy V = Val.template dyn_cast<EltTy>())
     94       return V;
     95     return Val.template get<VecTy*>()->front();
     96   }
     97 
     98   void push_back(EltTy NewVal) {
     99     assert(NewVal != 0 && "Can't add a null value");
    100 
    101     // If we have nothing, add something.
    102     if (Val.isNull()) {
    103       Val = NewVal;
    104       return;
    105     }
    106 
    107     // If we have a single value, convert to a vector.
    108     if (EltTy V = Val.template dyn_cast<EltTy>()) {
    109       Val = new VecTy();
    110       Val.template get<VecTy*>()->push_back(V);
    111     }
    112 
    113     // Add the new value, we know we have a vector.
    114     Val.template get<VecTy*>()->push_back(NewVal);
    115   }
    116 
    117   void clear() {
    118     // If we have a single value, convert to empty.
    119     if (Val.template is<EltTy>()) {
    120       Val = (EltTy)0;
    121     } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
    122       // If we have a vector form, just clear it.
    123       Vec->clear();
    124     }
    125     // Otherwise, we're already empty.
    126   }
    127 
    128 private:
    129   void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
    130 };
    131 } // end namespace llvm
    132 
    133 #endif
    134