3#include <Foundation/Basics.h>
10template <
typename PtrType, plUInt8 NumFlagBits = 2>
16 AllOnes = (std::size_t)(-1),
17 PtrBits =
sizeof(
void*) * 8,
18 FlagsMask = (AllOnes >> (PtrBits - NumFlagBits)),
22 void* m_pPtr =
nullptr;
34 const std::uintptr_t isrc = *
reinterpret_cast<std::uintptr_t*
>(&pPtr);
35 std::uintptr_t& iptr = *
reinterpret_cast<std::uintptr_t*
>(&m_pPtr);
37 iptr = (isrc & PtrMask) | (uiFlags & FlagsMask);
43 const std::uintptr_t& iptr = *
reinterpret_cast<const std::uintptr_t*
>(&m_pPtr);
44 return reinterpret_cast<const PtrType*
>(iptr & PtrMask);
50 std::uintptr_t& iptr = *
reinterpret_cast<std::uintptr_t*
>(&m_pPtr);
51 return reinterpret_cast<PtrType*
>(iptr & PtrMask);
57 const std::uintptr_t isrc = *
reinterpret_cast<std::uintptr_t*
>(&pPtr);
59 (isrc & FlagsMask) == 0,
"The given pointer does not have an {} byte alignment and thus cannot be stored lossless.", 1u << NumFlagBits);
61 std::uintptr_t& iptr = *
reinterpret_cast<std::uintptr_t*
>(&m_pPtr);
63 iptr = (isrc & PtrMask) | (iptr & FlagsMask);
68 const std::uintptr_t& iptr = *
reinterpret_cast<const std::uintptr_t*
>(&m_pPtr);
69 return static_cast<plUInt8
>(iptr & FlagsMask);
75 PL_ASSERT_DEBUG(uiFlags <= FlagsMask,
"The flag value {} requires more than {} bits", uiFlags, NumFlagBits);
77 std::uintptr_t& iptr = *
reinterpret_cast<std::uintptr_t*
>(&m_pPtr);
79 iptr = (iptr & PtrMask) | (uiFlags & FlagsMask);
83 operator PtrType*() {
return GetPtr(); }
86 operator const PtrType*()
const {
return GetPtr(); }
92 template <typename = typename std::enable_if<std::is_const<PtrType>::value ==
false>>
98#if PL_DISABLED(PL_USE_CPP20_OPERATORS)
100 template <typename = typename std::enable_if<std::is_const<PtrType>::value ==
false>>
101 bool operator!=(
const PtrType* pPtr)
const
103 return !(*
this == pPtr);
116 PL_ADD_DEFAULT_OPERATOR_NOTEQUAL(PtrType*);
120 PL_ADD_DEFAULT_OPERATOR_NOTEQUAL(std::nullptr_t);
123 explicit operator bool()
const {
return GetPtr() !=
nullptr; }
A wrapper around a raw pointer that allows to use the lower N bits for flags.
Definition PointerWithFlags.h:12
const PtrType & operator*() const
Dereferences the pointer.
Definition PointerWithFlags.h:132
void SetPtrAndFlags(PtrType *pPtr, plUInt8 uiFlags)
Changes the pointer and flags.
Definition PointerWithFlags.h:32
const PtrType * GetPtr() const
Returns the masked off pointer value.
Definition PointerWithFlags.h:41
PtrType * GetPtr()
Returns the masked off pointer value.
Definition PointerWithFlags.h:48
plPointerWithFlags(PtrType *pPtr, plUInt8 uiFlags=0)
Initializes the pointer and flags.
Definition PointerWithFlags.h:29
void SetPtr(PtrType *pPtr)
Changes the pointer value only. Flags stay unchanged.
Definition PointerWithFlags.h:55
bool operator==(PtrType *pPtr) const
Compares the pointer part for equality (flags are ignored)
Definition PointerWithFlags.h:115
plUInt8 GetFlags() const
Returns the flags value only.
Definition PointerWithFlags.h:66
bool operator==(const PtrType *pPtr) const
Compares the pointer part for equality (flags are ignored)
Definition PointerWithFlags.h:93
plPointerWithFlags()=default
Initializes the pointer and flags with zero.
void SetFlags(plUInt8 uiFlags)
Changes only the flags value. The given value must fit into the reserved bits.
Definition PointerWithFlags.h:73
bool operator==(std::nullptr_t) const
Compares the pointer part for equality (flags are ignored)
Definition PointerWithFlags.h:119
void operator=(PtrType *pPtr)
Changes the pointer value only. Flags stay unchanged.
Definition PointerWithFlags.h:89
PtrType * operator->()
Dereferences the pointer.
Definition PointerWithFlags.h:129
PtrType & operator*()
Dereferences the pointer.
Definition PointerWithFlags.h:135
const PtrType * operator->() const
Dereferences the pointer.
Definition PointerWithFlags.h:126