TinyPtrVector.h revision 0db235a2b0ed6ae5c3c870012061906054b6dbc4
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
16namespace 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///
24template <typename EltTy>
25class TinyPtrVector {
26public:
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  // implicit conversion operator to ArrayRef.
41  operator ArrayRef<EltTy>() const {
42    if (Val.isNull())
43      return ArrayRef<EltTy>();
44    if (Val.template is<EltTy>())
45      return *Val.template getAddrOf<EltTy>();
46    return *Val.template get<VecTy*>();
47  }
48
49  bool empty() const {
50    // This vector can be empty if it contains no element, or if it
51    // contains a pointer to an empty vector.
52    if (Val.isNull()) return true;
53    if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
54      return Vec->empty();
55    return false;
56  }
57
58  unsigned size() const {
59    if (empty())
60      return 0;
61    if (Val.template is<EltTy>())
62      return 1;
63    return Val.template get<VecTy*>()->size();
64  }
65
66  typedef const EltTy *iterator;
67  iterator begin() const {
68    if (empty())
69      return 0;
70
71    if (Val.template is<EltTy>())
72      return Val.getAddrOfPtr1();
73
74    return Val.template get<VecTy *>()->begin();
75
76  }
77  iterator end() const {
78    if (empty())
79      return 0;
80
81    if (Val.template is<EltTy>())
82      return begin() + 1;
83
84    return Val.template get<VecTy *>()->end();
85  }
86
87
88  EltTy operator[](unsigned i) const {
89    assert(!Val.isNull() && "can't index into an empty vector");
90    if (EltTy V = Val.template dyn_cast<EltTy>()) {
91      assert(i == 0 && "tinyvector index out of range");
92      return V;
93    }
94
95    assert(i < Val.template get<VecTy*>()->size() &&
96           "tinyvector index out of range");
97    return (*Val.template get<VecTy*>())[i];
98  }
99
100  EltTy front() const {
101    assert(!empty() && "vector empty");
102    if (EltTy V = Val.template dyn_cast<EltTy>())
103      return V;
104    return Val.template get<VecTy*>()->front();
105  }
106
107  void push_back(EltTy NewVal) {
108    assert(NewVal != 0 && "Can't add a null value");
109
110    // If we have nothing, add something.
111    if (Val.isNull()) {
112      Val = NewVal;
113      return;
114    }
115
116    // If we have a single value, convert to a vector.
117    if (EltTy V = Val.template dyn_cast<EltTy>()) {
118      Val = new VecTy();
119      Val.template get<VecTy*>()->push_back(V);
120    }
121
122    // Add the new value, we know we have a vector.
123    Val.template get<VecTy*>()->push_back(NewVal);
124  }
125
126  void clear() {
127    // If we have a single value, convert to empty.
128    if (Val.template is<EltTy>()) {
129      Val = (EltTy)0;
130    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
131      // If we have a vector form, just clear it.
132      Vec->clear();
133    }
134    // Otherwise, we're already empty.
135  }
136
137private:
138  void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
139};
140} // end namespace llvm
141
142#endif
143