TinyPtrVector.h revision 9d69d4aadd4a58aba5634d5c3d2c2a6d8d284134
19d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
29d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//
39d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//                     The LLVM Compiler Infrastructure
49d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//
59d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// This file is distributed under the University of Illinois Open Source
69d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// License. See LICENSE.TXT for details.
79d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//
89d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//===----------------------------------------------------------------------===//
99d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//
109d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// This file defines the Type class.
119d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//
129d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner//===----------------------------------------------------------------------===//
139d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
149d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner#ifndef LLVM_ADT_TINYPTRVECTOR_H
159d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner#define LLVM_ADT_TINYPTRVECTOR_H
169d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
179d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner#include "llvm/ADT/SmallVector.h"
189d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner#include "llvm/ADT/PointerUnion.h"
199d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
209d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnernamespace llvm {
219d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
229d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner/// TinyPtrVector - This class is specialized for cases where there are
239d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner/// normally 0 or 1 element in a vector, but is general enough to go beyond that
249d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner/// when required.
259d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner///
269d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner/// NOTE: This container doesn't allow you to store a null pointer into it.
279d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner///
289d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnertemplate <typename EltTy>
299d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerclass TinyPtrVector {
309d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerpublic:
319d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  typedef llvm::SmallVector<EltTy, 4> VecTy;
329d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  llvm::PointerUnion<EltTy, VecTy*> Val;
339d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
349d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  TinyPtrVector() {}
359d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
369d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (VecTy *V = Val.template dyn_cast<VecTy*>())
379d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Val = new VecTy(*V);
389d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
399d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  ~TinyPtrVector() {
409d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (VecTy *V = Val.template dyn_cast<VecTy*>())
419d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      delete V;
429d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
439d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
449d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  /// empty() - This vector can be empty if it contains no element, or if it
459d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  /// contains a pointer to an empty vector.
469d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  bool empty() const {
479d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (Val.isNull()) return true;
489d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
499d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return Vec->empty();
509d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    return false;
519d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
529d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
539d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  unsigned size() const {
549d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (empty())
559d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return 0;
569d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (Val. template is<EltTy>())
579d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return 1;
589d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    return Val. template get<VecTy*>()->size();
599d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
609d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
619d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  EltTy operator[](unsigned i) const {
629d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    assert(!Val.isNull() && "can't index into an empty vector");
639d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (EltTy V = Val.template dyn_cast<EltTy>()) {
649d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      assert(i == 0 && "tinyvector index out of range");
659d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return V;
669d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
679d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
689d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    assert(i < Val. template get<VecTy*>()->size() &&
699d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner           "tinyvector index out of range");
709d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    return (*Val. template get<VecTy*>())[i];
719d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
729d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
739d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  EltTy front() const {
749d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    assert(!empty() && "vector empty");
759d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (EltTy V = Val.template dyn_cast<EltTy>())
769d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return V;
779d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    return Val.template get<VecTy*>()->front();
789d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
799d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
809d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  void push_back(EltTy NewVal) {
819d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    assert(NewVal != 0 && "Can't add a null value");
829d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
839d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    // If we have nothing, add something.
849d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (Val.isNull()) {
859d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Val = NewVal;
869d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      return;
879d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
889d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
899d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    // If we have a single value, convert to a vector.
909d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (EltTy V = Val.template  dyn_cast<EltTy>()) {
919d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Val = new VecTy();
929d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Val.template get<VecTy*>()->push_back(V);
939d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
949d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
959d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    // Add the new value, we know we have a vector.
969d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    Val.template get<VecTy*>()->push_back(NewVal);
979d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
989d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
999d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  void clear() {
1009d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    // If we have a single value, convert to empty.
1019d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    if (EltTy V = Val.template dyn_cast<EltTy>()) {
1029d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Val = (EltTy)0;
1039d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
1049d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      // If we have a vector form, just clear it.
1059d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner      Vec->clear();
1069d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
1079d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    // Otherwise, we're already empty.
1089d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  }
1099d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1109d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerprivate:
1119d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner  void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
1129d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner};
1139d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner} // end namespace llvm
1149d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1159d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner#endif
116