From 9d69d4aadd4a58aba5634d5c3d2c2a6d8d284134 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 18 Jul 2011 01:40:02 +0000 Subject: [PATCH] introduce a new TinyPtrVector class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135365 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/ProgrammersManual.html | 19 +++++ include/llvm/ADT/TinyPtrVector.h | 115 +++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 include/llvm/ADT/TinyPtrVector.h diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 5565973ac1b..bfa721ddc95 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -59,6 +59,7 @@ option
  • llvm/ADT/ArrayRef.h
  • Fixed Size Arrays
  • Heap Allocated Arrays
  • +
  • "llvm/ADT/TinyPtrVector.h"
  • "llvm/ADT/SmallVector.h"
  • <vector>
  • <deque>
  • @@ -926,6 +927,24 @@ destructors will be run for every element in the array (re-sizable vectors only construct those elements actually used).

    + +

    + "llvm/ADT/TinyPtrVector.h" +

    + + +
    +

    TinyPtrVector<Type> is a highly specialized collection class +that is optimized to avoid allocation in the case when a vector has zero or one +elements. It has two major restrictions: 1) it can only hold values of pointer +type, and 2) it cannot hold a null pointer.

    + +

    Since this container is highly specialized, it is rarely used.

    + +
    + +
    +

    "llvm/ADT/SmallVector.h" diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h new file mode 100644 index 00000000000..e1dc3df5616 --- /dev/null +++ b/include/llvm/ADT/TinyPtrVector.h @@ -0,0 +1,115 @@ +//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Type class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_TINYPTRVECTOR_H +#define LLVM_ADT_TINYPTRVECTOR_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" + +namespace llvm { + +/// TinyPtrVector - This class is specialized for cases where there are +/// normally 0 or 1 element in a vector, but is general enough to go beyond that +/// when required. +/// +/// NOTE: This container doesn't allow you to store a null pointer into it. +/// +template +class TinyPtrVector { +public: + typedef llvm::SmallVector VecTy; + llvm::PointerUnion Val; + + TinyPtrVector() {} + TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) { + if (VecTy *V = Val.template dyn_cast()) + Val = new VecTy(*V); + } + ~TinyPtrVector() { + if (VecTy *V = Val.template dyn_cast()) + delete V; + } + + /// empty() - This vector can be empty if it contains no element, or if it + /// contains a pointer to an empty vector. + bool empty() const { + if (Val.isNull()) return true; + if (VecTy *Vec = Val.template dyn_cast()) + return Vec->empty(); + return false; + } + + unsigned size() const { + if (empty()) + return 0; + if (Val. template is()) + return 1; + return Val. template get()->size(); + } + + EltTy operator[](unsigned i) const { + assert(!Val.isNull() && "can't index into an empty vector"); + if (EltTy V = Val.template dyn_cast()) { + assert(i == 0 && "tinyvector index out of range"); + return V; + } + + assert(i < Val. template get()->size() && + "tinyvector index out of range"); + return (*Val. template get())[i]; + } + + EltTy front() const { + assert(!empty() && "vector empty"); + if (EltTy V = Val.template dyn_cast()) + return V; + return Val.template get()->front(); + } + + void push_back(EltTy NewVal) { + assert(NewVal != 0 && "Can't add a null value"); + + // If we have nothing, add something. + if (Val.isNull()) { + Val = NewVal; + return; + } + + // If we have a single value, convert to a vector. + if (EltTy V = Val.template dyn_cast()) { + Val = new VecTy(); + Val.template get()->push_back(V); + } + + // Add the new value, we know we have a vector. + Val.template get()->push_back(NewVal); + } + + void clear() { + // If we have a single value, convert to empty. + if (EltTy V = Val.template dyn_cast()) { + Val = (EltTy)0; + } else if (VecTy *Vec = Val.template dyn_cast()) { + // If we have a vector form, just clear it. + Vec->clear(); + } + // Otherwise, we're already empty. + } + +private: + void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. +}; +} // end namespace llvm + +#endif