diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-30 20:29:27 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-30 20:29:27 +0000 |
commit | 8db32a1e00d6098a04ae63ddb49f9fae8e3ad0dc (patch) | |
tree | 6c3894d3bf7af6ab223739a1ebeacce8c8c05060 /include/llvm/ADT | |
parent | d54b7e34debe9e945c4a4564c39294b6bc8a756d (diff) | |
download | external_llvm-8db32a1e00d6098a04ae63ddb49f9fae8e3ad0dc.zip external_llvm-8db32a1e00d6098a04ae63ddb49f9fae8e3ad0dc.tar.gz external_llvm-8db32a1e00d6098a04ae63ddb49f9fae8e3ad0dc.tar.bz2 |
add a PointerUnion3 class and generalize PointerUnion to work with
anything pointer-like, which may or may not actually be a pointer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68056 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/PointerUnion.h | 135 |
1 files changed, 120 insertions, 15 deletions
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 01272b8..da67c8e 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -22,12 +22,11 @@ namespace llvm { /// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return /// false or true respectively. template <typename PT1, typename PT2> - static inline bool getPointerUnionTypeNum(PT1 *P) { return false; } + static inline int getPointerUnionTypeNum(PT1 *P) { return 0; } template <typename PT1, typename PT2> - static inline bool getPointerUnionTypeNum(PT2 *P) { return true; } - // Enable, if we could use static_assert. - //template <typename PT1, typename PT2> - //static inline bool getPointerUnionTypeNum(...) { abort() } + static inline int getPointerUnionTypeNum(PT2 *P) { return 1; } + template <typename PT1, typename PT2> + static inline int getPointerUnionTypeNum(...) { return -1; } /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion @@ -70,22 +69,25 @@ namespace llvm { PointerUnion() {} PointerUnion(PT1 V) { - Val.setPointer(V); + Val.setPointer(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)); Val.setInt(0); } PointerUnion(PT2 V) { - Val.setPointer(V); + Val.setPointer(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)); Val.setInt(1); } /// isNull - Return true if the pointer help in the union is null, /// regardless of which type it is. bool isNull() const { return Val.getPointer() == 0; } - + operator bool() const { return !isNull(); } + /// is<T>() return true if the Union currently holds the type matching T. template<typename T> int is() const { - return Val.getInt() == ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); + int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); + assert(TyNo != -1 && "Type query could never succeed on PointerUnion!"); + return Val.getInt() == TyNo; } /// get<T>() - Return the value of the specified pointer type. If the @@ -93,26 +95,26 @@ namespace llvm { template<typename T> T get() const { assert(is<T>() && "Invalid accessor called"); - return static_cast<T>(Val.getPointer()); + return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer()); } /// dyn_cast<T>() - If the current value is of the specified pointer type, /// return it, otherwise return null. template<typename T> T dyn_cast() const { - if (is<T>()) return static_cast<T>(Val.getPointer()); + if (is<T>()) return get<T>(); return T(); } /// Assignment operators - Allow assigning into this union from either /// pointer type, setting the discriminator to remember what it came from. const PointerUnion &operator=(const PT1 &RHS) { - Val.setPointer(RHS); + Val.setPointer(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)); Val.setInt(0); return *this; } const PointerUnion &operator=(const PT2 &RHS) { - Val.setPointer(RHS); + Val.setPointer(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)); Val.setInt(1); return *this; } @@ -125,7 +127,7 @@ namespace llvm { } }; - // Teach SmallPtrSet that PointerIntPair is "basically a pointer", that has + // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. template<typename PT1, typename PT2> class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > { @@ -142,7 +144,110 @@ namespace llvm { // The number of bits available are the min of the two pointer types. enum { NumLowBitsAvailable = - PointerUnion<PT1,PT2>::ValTy::NumLowBitsAvailable + PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy> + ::NumLowBitsAvailable + }; + }; + + + /// PointerUnion3 - This is a pointer union of three pointer types. See + /// documentation for PointerUnion for usage. + template <typename PT1, typename PT2, typename PT3> + class PointerUnion3 { + public: + typedef PointerUnion<PT1, PT2> InnerUnion; + typedef PointerUnion<InnerUnion, PT3> ValTy; + private: + ValTy Val; + public: + PointerUnion3() {} + + PointerUnion3(PT1 V) { + Val = InnerUnion(V); + } + PointerUnion3(PT2 V) { + Val = InnerUnion(V); + } + PointerUnion3(PT3 V) { + Val = V; + } + + /// isNull - Return true if the pointer help in the union is null, + /// regardless of which type it is. + bool isNull() const { return Val.isNull(); } + operator bool() const { return !isNull(); } + + /// is<T>() return true if the Union currently holds the type matching T. + template<typename T> + int is() const { + // Is it PT1/PT2? + if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) + return Val.get<InnerUnion>().is<T>(); + // Must be PT3 or statically invalid. + assert(Val.is<T>()); + return true; + } + + /// get<T>() - Return the value of the specified pointer type. If the + /// specified pointer type is incorrect, assert. + template<typename T> + T get() const { + assert(is<T>() && "Invalid accessor called"); + if (Val.is<T>()) + return Val.get<T>(); + return Val.get<InnerUnion>().get<T>(); + } + + /// dyn_cast<T>() - If the current value is of the specified pointer type, + /// return it, otherwise return null. + template<typename T> + T dyn_cast() const { + if (is<T>()) return get<T>(); + return T(); + } + + /// Assignment operators - Allow assigning into this union from either + /// pointer type, setting the discriminator to remember what it came from. + const PointerUnion3 &operator=(const PT1 &RHS) { + Val = InnerUnion(RHS); + return *this; + } + const PointerUnion3 &operator=(const PT2 &RHS) { + Val = InnerUnion(RHS); + return *this; + } + const PointerUnion3 &operator=(const PT3 &RHS) { + Val = RHS; + return *this; + } + + void *getOpaqueValue() const { return Val.getOpaqueValue(); } + static PointerUnion3 getFromOpaqueValue(void *VP) { + PointerUnion3 V; + V.Val = ValTy::getFromOpaqueValue(VP); + return V; + } + }; + + // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has + // # low bits available = min(PT1bits,PT2bits,PT2bits)-2. + template<typename PT1, typename PT2, typename PT3> + class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > { + public: + static inline void * + getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) { + return P.getOpaqueValue(); + } + static inline PointerUnion3<PT1, PT2, PT3> + getFromVoidPointer(void *P) { + return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P); + } + + // The number of bits available are the min of the two pointer types. + enum { + NumLowBitsAvailable = + PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy> + ::NumLowBitsAvailable }; }; } |