//===- 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/PointerLikeTypeTraits.h"
#include <cassert>
#include <cstdint>
#include <cstddef>

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() = default;

  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() = default;

  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() = default;

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

} // end namespace llvm

#endif // LLVM_ADT_POINTERUNION_H
