3 #include "../utility/assert.h"
4 #include "../utility/bits.h"
15 template<
typename PtrT,
size_t Bits,
size_t Alignment>
22 static_assert(Bits <=
FREE_BITS,
"The number of bits in use cannot surpass the number of free bits");
24 static constexpr uintptr_t INT_MASK = ((1ULL << Bits) - 1);
25 static constexpr uintptr_t PTR_MASK = ~((1ULL <<
FREE_BITS) - 1);
29 m_Value(reinterpret_cast<uintptr_t>(
nullptr)) {}
31 template<
typename Int>
33 m_Value((
reinterpret_cast<uintptr_t
>(p) & PTR_MASK) | (
static_cast<uintptr_t
>(value) & INT_MASK))
35 static_assert(std::is_unsigned_v<Int>,
"Packed integer must be unsigned");
38 KTL_ASSERT((
reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
41 explicit operator bool() const noexcept {
return m_Value; }
43 PtrT
get_ptr() const noexcept {
return reinterpret_cast<PtrT
>(m_Value & PTR_MASK); }
45 template<
typename Int>
48 static_assert(std::is_unsigned_v<Int>,
"Packed integer must be unsigned");
50 return static_cast<Int
>(m_Value & INT_MASK);
56 KTL_ASSERT((
reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
58 m_Value = (
reinterpret_cast<uintptr_t
>(p) & PTR_MASK) | (m_Value & INT_MASK);
61 template<
typename Int>
64 static_assert(std::is_unsigned_v<Int>,
"Packed integer must be unsigned");
66 m_Value = (m_Value & PTR_MASK) | (
static_cast<uintptr_t
>(value) & INT_MASK);
#define KTL_ASSERT(x)
Definition: assert.h:17
A packed pointer-like type which takes advantage of any bits that don't get used due to alignment.
Definition: packed_ptr.h:17
static constexpr uintmax_t FREE_BITS
Definition: packed_ptr.h:19
void set_ptr(PtrT p) noexcept
Definition: packed_ptr.h:53
packed_ptr() noexcept
Definition: packed_ptr.h:28
Int get_int() const noexcept
Definition: packed_ptr.h:46
void set_int(Int value) noexcept
Definition: packed_ptr.h:62
packed_ptr(PtrT p, Int value) noexcept
Definition: packed_ptr.h:32
PtrT get_ptr() const noexcept
Definition: packed_ptr.h:43
constexpr uintmax_t log2(uintmax_t n) noexcept
Definition: bits.h:7
Definition: cascading.h:15