14 #ifndef WPIUTIL_WPI_POINTERINTPAIR_H
15 #define WPIUTIL_WPI_POINTERINTPAIR_H
17 #include "wpi/PointerLikeTypeTraits.h"
24 template <
typename T>
struct DenseMapInfo;
25 template <
typename Po
interT,
unsigned IntBits,
typename PtrTraits>
41 template <
typename PointerTy,
unsigned IntBits,
typename IntType = unsigned,
53 setPointerAndInt(PtrVal, IntVal);
56 explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
58 PointerTy getPointer()
const {
return Info::getPointer(Value); }
60 IntType getInt()
const {
return (IntType)Info::getInt(Value); }
62 void setPointer(PointerTy PtrVal) {
63 Value = Info::updatePointer(Value, PtrVal);
66 void setInt(IntType IntVal) {
67 Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal));
70 void initWithPointer(PointerTy PtrVal) {
71 Value = Info::updatePointer(0, PtrVal);
74 void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
75 Value = Info::updateInt(Info::updatePointer(0, PtrVal),
76 static_cast<intptr_t>(IntVal));
79 PointerTy
const *getAddrOfPointer()
const {
80 return const_cast<PointerIntPair *>(
this)->getAddrOfPointer();
83 PointerTy *getAddrOfPointer() {
84 assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
85 "Can only return the address if IntBits is cleared and "
86 "PtrTraits doesn't change the pointer");
87 return reinterpret_cast<PointerTy *>(&Value);
90 void *getOpaqueValue()
const {
return reinterpret_cast<void *>(Value); }
92 void setFromOpaqueValue(
void *Val) {
93 Value = reinterpret_cast<intptr_t>(Val);
98 P.setFromOpaqueValue(V);
105 (void)PtrTraits::getFromVoidPointer(V);
106 return getFromOpaqueValue(const_cast<void *>(V));
110 return Value == RHS.Value;
114 return Value != RHS.Value;
117 bool operator<(
const PointerIntPair &RHS)
const {
return Value < RHS.Value; }
118 bool operator>(
const PointerIntPair &RHS)
const {
return Value > RHS.Value; }
121 return Value <= RHS.Value;
125 return Value >= RHS.Value;
129 template <
typename Po
interT,
unsigned IntBits,
typename PtrTraits>
131 static_assert(PtrTraits::NumLowBitsAvailable <
132 std::numeric_limits<uintptr_t>::digits,
133 "cannot use a pointer type that has all bits free");
134 static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
135 "PointerIntPair with integer size too large for pointer");
139 ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
143 IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
146 IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
152 static PointerT getPointer(intptr_t Value) {
153 return PtrTraits::getFromVoidPointer(
157 static intptr_t getInt(intptr_t Value) {
161 static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
163 reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
165 "Pointer is not sufficiently aligned");
170 static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
171 intptr_t IntWord = static_cast<intptr_t>(Int);
172 assert((IntWord & ~
IntMask) == 0 &&
"Integer too large for field");
175 return (OrigValue & ~ShiftedIntMask) | IntWord <<
IntShift;
179 template <
typename T>
struct isPodLike;
180 template <
typename Po
interTy,
unsigned IntBits,
typename IntType>
182 static const bool value =
true;
186 template <
typename Po
interTy,
unsigned IntBits,
typename IntType>
190 static Ty getEmptyKey() {
191 uintptr_t Val = static_cast<uintptr_t>(-1);
192 Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
193 return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
196 static Ty getTombstoneKey() {
197 uintptr_t Val = static_cast<uintptr_t>(-2);
198 Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
199 return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
202 static unsigned getHashValue(
Ty V) {
203 uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
204 return unsigned(IV) ^ unsigned(IV >> 9);
207 static bool isEqual(
const Ty &LHS,
const Ty &RHS) {
return LHS == RHS; }
211 template <
typename PointerTy,
unsigned IntBits,
typename IntType,
217 return P.getOpaqueValue();
221 getFromVoidPointer(
void *P) {
226 getFromVoidPointer(
const void *P) {
230 enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
235 #endif // WPIUTIL_WPI_POINTERINTPAIR_H