//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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 PointerUnion class, which is a discriminated union of
// pointer types.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_POINTERUNION_H
#define LLVM_ADT_POINTERUNION_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"

namespace llvm {

  template <typename T>
  struct PointerUnionTypeSelectorReturn {
    typedef T Return;
  };

  /// \brief Get a type based on whether two types are the same or not. For:
  /// @code
  /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
  /// @endcode
  /// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
  template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
  struct PointerUnionTypeSelector {
    typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
  };

  template <typename T, typename RET_EQ, typename RET_NE>
  struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
    typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
  };

  template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
  struct PointerUnionTypeSelectorReturn<
                            PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
    typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
        Return;
  };

  /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
  /// for the two template arguments.
  template <typename PT1, typename PT2>
  class PointerUnionUIntTraits {
  public:
    static inline void *getAsVoidPointer(void *P) { return P; }
    static inline void *getFromVoidPointer(void *P) { return P; }
    enum {
      PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
      PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
      NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
    };
  };

  /// PointerUnion - This implements a discriminated union of two pointer types,
  /// and keeps the discriminator bit-mangled into the low bits of the pointer.
  /// This allows the implementation to be extremely efficient in space, but
  /// permits a very natural and type-safe API.
  ///
  /// Common use patterns would be something like this:
  ///    PointerUnion<int*, float*> P;
  ///    P = (int*)0;
  ///    printf("%d %d", P.is<int*>(), P.is<float*>());  // prints "1 0"
  ///    X = P.get<int*>();     // ok.
  ///    Y = P.get<float*>();   // runtime assertion failure.
  ///    Z = P.get<double*>();  // compile time failure.
  ///    P = (float*)0;
  ///    Y = P.get<float*>();   // ok.
  ///    X = P.get<int*>();     // runtime assertion failure.
  template <typename PT1, typename PT2>
  class PointerUnion {
  public:
    typedef PointerIntPair<void*, 1, bool,
                           PointerUnionUIntTraits<PT1,PT2> > ValTy;
  private:
    ValTy Val;

    struct IsPT1 {
      static const int Num = 0;
    };
    struct IsPT2 {
      static const int Num = 1;
    };
    template <typename T>
    struct UNION_DOESNT_CONTAIN_TYPE { };

  public:
    PointerUnion() {}

    PointerUnion(PT1 V) : Val(
      const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
    }
    PointerUnion(PT2 V) : Val(
      const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
    }

    /// isNull - Return true if the pointer held in the union is null,
    /// regardless of which type it is.
    bool isNull() const {
      // Convert from the void* to one of the pointer types, to make sure that
      // we recursively strip off low bits if we have a nested PointerUnion.
      return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
    }
    explicit operator bool() const { return !isNull(); }

    /// is<T>() return true if the Union currently holds the type matching T.
    template<typename T>
    int is() const {
      typedef typename
        ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
          ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
                                    UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
      int TyNo = Ty::Num;
      return static_cast<int>(Val.getInt()) == TyNo;
    }

    /// 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");
      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 get<T>();
      return T();
    }

    /// \brief If the union is set to the first pointer type get an address
    /// pointing to it.
    PT1 const *getAddrOfPtr1() const {
      return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
    }

    /// \brief If the union is set to the first pointer type get an address
    /// pointing to it.
    PT1 *getAddrOfPtr1() {
      assert(is<PT1>() && "Val is not the first pointer");
      assert(get<PT1>() == Val.getPointer() &&
         "Can't get the address because PointerLikeTypeTraits changes the ptr");
      return (PT1 *)Val.getAddrOfPointer();
    }

    /// \brief Assignment from nullptr which just clears the union.
    const PointerUnion &operator=(std::nullptr_t) {
      Val.initWithPointer(nullptr);
      return *this;
    }

    /// 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.initWithPointer(
         const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
      return *this;
    }
    const PointerUnion &operator=(const PT2 &RHS) {
      Val.setPointerAndInt(
        const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
        1);
      return *this;
    }

    void *getOpaqueValue() const { return Val.getOpaqueValue(); }
    static inline PointerUnion getFromOpaqueValue(void *VP) {
      PointerUnion V;
      V.Val = ValTy::getFromOpaqueValue(VP);
      return V;
    }
  };

  template<typename PT1, typename PT2>
  static bool operator==(PointerUnion<PT1, PT2> lhs,
                         PointerUnion<PT1, PT2> rhs) {
    return lhs.getOpaqueValue() == rhs.getOpaqueValue();
  }

  template<typename PT1, typename PT2>
  static bool operator!=(PointerUnion<PT1, PT2> lhs,
                         PointerUnion<PT1, PT2> rhs) {
    return lhs.getOpaqueValue() != rhs.getOpaqueValue();
  }

  template<typename PT1, typename PT2>
  static bool operator<(PointerUnion<PT1, PT2> lhs,
                        PointerUnion<PT1, PT2> rhs) {
    return lhs.getOpaqueValue() < rhs.getOpaqueValue();
  }

  // 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> > {
  public:
    static inline void *
    getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
      return P.getOpaqueValue();
    }
    static inline PointerUnion<PT1, PT2>
    getFromVoidPointer(void *P) {
      return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
    }

    // The number of bits available are the min of the two pointer types.
    enum {
      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;

    struct IsInnerUnion {
      ValTy Val;
      IsInnerUnion(ValTy val) : Val(val) { }
      template<typename T>
      int is() const {
        return Val.template is<InnerUnion>() &&
               Val.template get<InnerUnion>().template is<T>();
      }
      template<typename T>
      T get() const {
        return Val.template get<InnerUnion>().template get<T>();
      }
    };

    struct IsPT3 {
      ValTy Val;
      IsPT3(ValTy val) : Val(val) { }
      template<typename T>
      int is() const {
        return Val.template is<T>();
      }
      template<typename T>
      T get() const {
        return Val.template get<T>();
      }
    };

  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 held in the union is null,
    /// regardless of which type it is.
    bool isNull() const { return Val.isNull(); }
    explicit operator bool() const { return !isNull(); }

    /// is<T>() return true if the Union currently holds the type matching T.
    template<typename T>
    int is() const {
      // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
      typedef typename
        ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
          ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
                                                                   >::Return Ty;
      return Ty(Val).template is<T>();
    }

    /// 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 T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
      typedef typename
        ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
          ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
                                                                   >::Return Ty;
      return Ty(Val).template 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();
    }

    /// \brief Assignment from nullptr which just clears the union.
    const PointerUnion3 &operator=(std::nullptr_t) {
      Val = nullptr;
      return *this;
    }

    /// 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 inline 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
    };
  };

  /// PointerUnion4 - This is a pointer union of four pointer types.  See
  /// documentation for PointerUnion for usage.
  template <typename PT1, typename PT2, typename PT3, typename PT4>
  class PointerUnion4 {
  public:
    typedef PointerUnion<PT1, PT2> InnerUnion1;
    typedef PointerUnion<PT3, PT4> InnerUnion2;
    typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
  private:
    ValTy Val;
  public:
    PointerUnion4() {}

    PointerUnion4(PT1 V) {
      Val = InnerUnion1(V);
    }
    PointerUnion4(PT2 V) {
      Val = InnerUnion1(V);
    }
    PointerUnion4(PT3 V) {
      Val = InnerUnion2(V);
    }
    PointerUnion4(PT4 V) {
      Val = InnerUnion2(V);
    }

    /// isNull - Return true if the pointer held in the union is null,
    /// regardless of which type it is.
    bool isNull() const { return Val.isNull(); }
    explicit operator bool() const { return !isNull(); }

    /// is<T>() return true if the Union currently holds the type matching T.
    template<typename T>
    int is() const {
      // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
      typedef typename
        ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
          ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
                                                                   >::Return Ty;
      return Val.template is<Ty>() &&
             Val.template get<Ty>().template is<T>();
    }

    /// 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 T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
      typedef typename
        ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
          ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
                                                                   >::Return Ty;
      return Val.template get<Ty>().template 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();
    }

    /// \brief Assignment from nullptr which just clears the union.
    const PointerUnion4 &operator=(std::nullptr_t) {
      Val = nullptr;
      return *this;
    }

    /// Assignment operators - Allow assigning into this union from either
    /// pointer type, setting the discriminator to remember what it came from.
    const PointerUnion4 &operator=(const PT1 &RHS) {
      Val = InnerUnion1(RHS);
      return *this;
    }
    const PointerUnion4 &operator=(const PT2 &RHS) {
      Val = InnerUnion1(RHS);
      return *this;
    }
    const PointerUnion4 &operator=(const PT3 &RHS) {
      Val = InnerUnion2(RHS);
      return *this;
    }
    const PointerUnion4 &operator=(const PT4 &RHS) {
      Val = InnerUnion2(RHS);
      return *this;
    }

    void *getOpaqueValue() const { return Val.getOpaqueValue(); }
    static inline PointerUnion4 getFromOpaqueValue(void *VP) {
      PointerUnion4 V;
      V.Val = ValTy::getFromOpaqueValue(VP);
      return V;
    }
  };

  // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
  // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
  template<typename PT1, typename PT2, typename PT3, typename PT4>
  class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
  public:
    static inline void *
    getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
      return P.getOpaqueValue();
    }
    static inline PointerUnion4<PT1, PT2, PT3, PT4>
    getFromVoidPointer(void *P) {
      return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
    }

    // The number of bits available are the min of the two pointer types.
    enum {
      NumLowBitsAvailable =
        PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
          ::NumLowBitsAvailable
    };
  };

  // Teach DenseMap how to use PointerUnions as keys.
  template<typename T, typename U>
  struct DenseMapInfo<PointerUnion<T, U> > {
    typedef PointerUnion<T, U> Pair;
    typedef DenseMapInfo<T> FirstInfo;
    typedef DenseMapInfo<U> SecondInfo;

    static inline Pair getEmptyKey() {
      return Pair(FirstInfo::getEmptyKey());
    }
    static inline Pair getTombstoneKey() {
      return Pair(FirstInfo::getTombstoneKey());
    }
    static unsigned getHashValue(const Pair &PairVal) {
      intptr_t key = (intptr_t)PairVal.getOpaqueValue();
      return DenseMapInfo<intptr_t>::getHashValue(key);
    }
    static bool isEqual(const Pair &LHS, const Pair &RHS) {
      return LHS.template is<T>() == RHS.template is<T>() &&
             (LHS.template is<T>() ?
              FirstInfo::isEqual(LHS.template get<T>(),
                                 RHS.template get<T>()) :
              SecondInfo::isEqual(LHS.template get<U>(),
                                  RHS.template get<U>()));
    }
  };
}

#endif
