llvm/llvm/include/llvm/ADT/PointerIntPair.h

//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the PointerIntPair class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_POINTERINTPAIR_H
#define LLVM_ADT_POINTERINTPAIR_H

#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstdint>
#include <cstring>
#include <limits>

namespace llvm {

namespace detail {
template <typename Ptr> struct PunnedPointer {};
} // namespace detail

template <typename T, typename Enable> struct DenseMapInfo;
template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo;

/// PointerIntPair - This class implements a pair of a pointer and small
/// integer.  It is designed to represent this in the space required by one
/// pointer by bitmangling the integer into the low part of the pointer.  This
/// can only be done for small integers: typically up to 3 bits, but it depends
/// on the number of bits available according to PointerLikeTypeTraits for the
/// type.
///
/// Note that PointerIntPair always puts the IntVal part in the highest bits
/// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
/// the bool into bit #2, not bit #0, which allows the low two bits to be used
/// for something else.  For example, this allows:
///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
/// ... and the two bools will land in different bits.
template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
          typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
          typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
class PointerIntPair {
  // Used by MSVC visualizer and generally helpful for debugging/visualizing.
  using InfoTy = Info;
  detail::PunnedPointer<PointerTy> Value;

public:
  constexpr PointerIntPair() = default;

  PointerIntPair(PointerTy PtrVal, IntType IntVal) {}

  explicit PointerIntPair(PointerTy PtrVal) {}

  PointerTy getPointer() const {}

  IntType getInt() const {}

  void setPointer(PointerTy PtrVal) & {}

  void setInt(IntType IntVal) & {}

  void initWithPointer(PointerTy PtrVal) & {}

  void setPointerAndInt(PointerTy PtrVal, IntType IntVal) & {}

  PointerTy const *getAddrOfPointer() const {}

  PointerTy *getAddrOfPointer() {}

  void *getOpaqueValue() const {}

  void setFromOpaqueValue(void *Val) & {}

  static PointerIntPair getFromOpaqueValue(void *V) {}

  // Allow PointerIntPairs to be created from const void * if and only if the
  // pointer type could be created from a const void *.
  static PointerIntPair getFromOpaqueValue(const void *V) {}

  bool operator==(const PointerIntPair &RHS) const {}

  bool operator!=(const PointerIntPair &RHS) const {}

  bool operator<(const PointerIntPair &RHS) const {}
  bool operator>(const PointerIntPair &RHS) const {}

  bool operator<=(const PointerIntPair &RHS) const {}

  bool operator>=(const PointerIntPair &RHS) const {}
};

template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo {};

// Provide specialization of DenseMapInfo for PointerIntPair.
DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>, void>;

// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>>;

// Allow structured bindings on PointerIntPair.
template <std::size_t I, typename PointerTy, unsigned IntBits, typename IntType,
          typename PtrTraits, typename Info>
decltype(auto)
get(const PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info> &Pair) {}

} // end namespace llvm

namespace std {
tuple_size<llvm::PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>;

tuple_element<I, llvm::PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>;
} // namespace std

#endif // LLVM_ADT_POINTERINTPAIR_H