15 #ifndef WPIUTIL_WPI_POINTERUNION_H
16 #define WPIUTIL_WPI_POINTERUNION_H
18 #include "wpi/DenseMapInfo.h"
19 #include "wpi/PointerIntPair.h"
20 #include "wpi/PointerLikeTypeTraits.h"
40 template <
typename T1,
typename T2,
typename RET_EQ,
typename RET_NE>
42 using Return =
typename PointerUnionTypeSelectorReturn<RET_NE>::Return;
45 template <
typename T,
typename RET_EQ,
typename RET_NE>
47 using Return =
typename PointerUnionTypeSelectorReturn<RET_EQ>::Return;
50 template <
typename T1,
typename T2,
typename RET_EQ,
typename RET_NE>
54 typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return;
61 static inline void *getAsVoidPointer(
void *P) {
return P; }
62 static inline void *getFromVoidPointer(
void *P) {
return P; }
67 NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
96 static const int Num = 0;
99 static const int Num = 1;
101 template <
typename T>
struct UNION_DOESNT_CONTAIN_TYPE {};
106 : Val(const_cast<void *>(
120 explicit operator bool()
const {
return !
isNull(); }
123 template <
typename T>
int is()
const {
124 using Ty = typename ::wpi::PointerUnionTypeSelector<
127 UNION_DOESNT_CONTAIN_TYPE<T>>>::Return;
129 return static_cast<int>(Val.getInt()) == TyNo;
135 template <
typename T> T
get()
const {
136 assert(is<T>() &&
"Invalid accessor called");
151 return const_cast<PointerUnion *>(
this)->getAddrOfPtr1();
157 assert(is<PT1>() &&
"Val is not the first pointer");
159 get<PT1>() == Val.getPointer() &&
160 "Can't get the address because PointerLikeTypeTraits changes the ptr");
161 return const_cast<PT1 *>(
162 reinterpret_cast<const PT1 *>(Val.getAddrOfPointer()));
167 Val.initWithPointer(
nullptr);
179 Val.setPointerAndInt(
185 void *getOpaqueValue()
const {
return Val.getOpaqueValue(); }
186 static inline PointerUnion getFromOpaqueValue(
void *VP) {
188 V.Val = ValTy::getFromOpaqueValue(VP);
193 template <
typename PT1,
typename PT2>
194 bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
195 return lhs.getOpaqueValue() == rhs.getOpaqueValue();
198 template <
typename PT1,
typename PT2>
199 bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
200 return lhs.getOpaqueValue() != rhs.getOpaqueValue();
203 template <
typename PT1,
typename PT2>
204 bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
205 return lhs.getOpaqueValue() < rhs.getOpaqueValue();
210 template <
typename PT1,
typename PT2>
213 return P.getOpaqueValue();
237 struct IsInnerUnion {
240 IsInnerUnion(
ValTy val) : Val(val) {}
242 template <
typename T>
int is()
const {
243 return Val.template is<InnerUnion>() &&
244 Val.template get<InnerUnion>().template is<T>();
247 template <
typename T> T
get()
const {
248 return Val.template get<InnerUnion>().template get<T>();
255 IsPT3(
ValTy val) : Val(val) {}
257 template <
typename T>
int is()
const {
return Val.template is<T>(); }
258 template <
typename T> T
get()
const {
return Val.template get<T>(); }
270 explicit operator bool()
const {
return !
isNull(); }
273 template <
typename T>
int is()
const {
275 using Ty = typename ::wpi::PointerUnionTypeSelector<
276 PT1, T, IsInnerUnion,
278 return Ty(Val).template is<T>();
284 template <
typename T> T
get()
const {
285 assert(is<T>() &&
"Invalid accessor called");
287 using Ty = typename ::wpi::PointerUnionTypeSelector<
288 PT1, T, IsInnerUnion,
290 return Ty(Val).template get<T>();
314 Val = InnerUnion(RHS);
317 const PointerUnion3 &
operator=(
const PT3 &RHS) {
322 void *getOpaqueValue()
const {
return Val.getOpaqueValue(); }
323 static inline PointerUnion3 getFromOpaqueValue(
void *VP) {
325 V.Val = ValTy::getFromOpaqueValue(VP);
332 template <
typename PT1,
typename PT2,
typename PT3>
335 return P.getOpaqueValue();
349 template <
typename PT1,
typename PT2,
typename PT3>
352 return lhs.getOpaqueValue() < rhs.getOpaqueValue();
357 template <
typename PT1,
typename PT2,
typename PT3,
typename PT4>
377 explicit operator bool()
const {
return !
isNull(); }
380 template <
typename T>
int is()
const {
382 using Ty = typename ::wpi::PointerUnionTypeSelector<
386 return Val.template is<Ty>() && Val.template get<Ty>().template is<T>();
392 template <
typename T> T
get()
const {
393 assert(is<T>() &&
"Invalid accessor called");
395 using Ty = typename ::wpi::PointerUnionTypeSelector<
399 return Val.template get<Ty>().template get<T>();
423 Val = InnerUnion1(RHS);
426 const PointerUnion4 &
operator=(
const PT3 &RHS) {
427 Val = InnerUnion2(RHS);
430 const PointerUnion4 &
operator=(
const PT4 &RHS) {
431 Val = InnerUnion2(RHS);
435 void *getOpaqueValue()
const {
return Val.getOpaqueValue(); }
436 static inline PointerUnion4 getFromOpaqueValue(
void *VP) {
438 V.Val = ValTy::getFromOpaqueValue(VP);
445 template <
typename PT1,
typename PT2,
typename PT3,
typename PT4>
449 return P.getOpaqueValue();
469 static inline Pair getEmptyKey() {
return Pair(FirstInfo::getEmptyKey()); }
471 static inline Pair getTombstoneKey() {
472 return Pair(FirstInfo::getTombstoneKey());
475 static unsigned getHashValue(
const Pair &PairVal) {
476 intptr_t key = (intptr_t)PairVal.getOpaqueValue();
480 static bool isEqual(
const Pair &LHS,
const Pair &RHS) {
481 return LHS.template is<T>() == RHS.template is<T>() &&
482 (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(),
483 RHS.template get<T>())
484 : SecondInfo::isEqual(LHS.template get<U>(),
485 RHS.template get<U>()));
491 #endif // WPIUTIL_WPI_POINTERUNION_H
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:123
bool isNull() const
Test if the pointer held in the union is null, regardless of which type it is.
Definition: PointerUnion.h:376
const PointerUnion & operator=(const PT1 &RHS)
Assignment operators - Allow assigning into this union from either pointer type, setting the discrimi...
Definition: PointerUnion.h:173
PT1 * getAddrOfPtr1()
If the union is set to the first pointer type get an address pointing to it.
Definition: PointerUnion.h:156
bool isNull() const
Test if the pointer held in the union is null, regardless of which type it is.
Definition: PointerUnion.h:269
const PointerUnion3 & operator=(const PT1 &RHS)
Assignment operators - Allow assigning into this union from either pointer type, setting the discrimi...
Definition: PointerUnion.h:309
const PointerUnion3 & operator=(std::nullptr_t)
Assignment from nullptr which just clears the union.
Definition: PointerUnion.h:302
Provide PointerLikeTypeTraits for void* that is used by PointerUnion for the two template arguments.
Definition: PointerUnion.h:59
const PointerUnion4 & operator=(const PT1 &RHS)
Assignment operators - Allow assigning into this union from either pointer type, setting the discrimi...
Definition: PointerUnion.h:418
Definition: PointerUnion.h:27
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:273
const PointerUnion & operator=(std::nullptr_t)
Assignment from nullptr which just clears the union.
Definition: PointerUnion.h:166
WPILib C++ utilities (wpiutil) namespace.
Definition: EventLoopRunner.h:17
Get a type based on whether two types are the same or not.
Definition: PointerUnion.h:41
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:135
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:284
bool isNull() const
Test if the pointer held in the union is null, regardless of which type it is.
Definition: PointerUnion.h:114
A discriminated union of two pointer types, with the discriminator in the low bit of the pointer.
Definition: PointerUnion.h:87
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwises returns null.
Definition: PointerUnion.h:142
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwises returns null.
Definition: PointerUnion.h:404
const PointerUnion4 & operator=(std::nullptr_t)
Assignment from nullptr which just clears the union.
Definition: PointerUnion.h:411
A pointer union of four pointer types.
Definition: PointerUnion.h:358
A traits type that is used to handle pointer types and things that are just wrappers for pointers as ...
Definition: PointerLikeTypeTraits.h:26
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:380
Definition: DenseMapInfo.h:29
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:392
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwises returns null.
Definition: PointerUnion.h:295
const PT1 * getAddrOfPtr1() const
If the union is set to the first pointer type get an address pointing to it.
Definition: PointerUnion.h:150
A pointer union of three pointer types.
Definition: PointerUnion.h:229