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

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

/// A discriminated union of two pointer types, with the discriminator in the
/// low bit of the pointer.
///
/// This implementation is extremely efficient in space due to leveraging the
/// low bits of the pointer, while exposing a 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) {}

  /// Test 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(); }

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

  /// Returns 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());
  }

  /// Returns the current pointer if it is of the specified pointer type,
  /// otherwises returns null.
  template <typename T> T dyn_cast() const {
    if (is<T>())
      return get<T>();
    return T();
  }

  /// 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();
  }

  /// 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();
  }

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

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

  /// Test 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(); }

  /// Test 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>();
  }

  /// Returns 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>();
  }

  /// Returns the current pointer if it is of the specified pointer type,
  /// otherwises returns null.
  template <typename T> T dyn_cast() const {
    if (is<T>())
      return get<T>();
    return T();
  }

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

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

  /// Test 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(); }

  /// Test 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>();
  }

  /// Returns 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>();
  }

  /// Returns the current pointer if it is of the specified pointer type,
  /// otherwises returns null.
  template <typename T> T dyn_cast() const {
    if (is<T>())
      return get<T>();
    return T();
  }

  /// 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
