3#include "../utility/assert.h"
4#include "../utility/bits.h"
16 template<
typename PtrT,
typename IntT, IntT Min, IntT Max,
size_t Alignment>
27 static_assert(!std::is_const_v<PtrT>,
"Pointer type cannot be const");
28 static_assert(!std::is_const_v<IntT>,
"Integer type cannot be const");
29 static_assert(std::is_pointer_v<PtrT>,
"Type must be a pointer");
30 static_assert(
UsedBits <=
FreeBits,
"The number of bits in use cannot surpass the number of free bits");
31 static_assert(std::is_integral_v<IntT> || std::is_enum_v<IntT>,
"The packed type must be an integer, bool or enum");
33 static constexpr uintptr_t INT_MASK = (1ULL <<
UsedBits) - 1ULL;
34 static constexpr uintptr_t PTR_MASK = ~((1ULL <<
FreeBits) - 1ULL);
35 static constexpr uintptr_t SIGNED_INT_MIN = 1ULL << (
UsedBits - 1ULL);
39 m_Value(reinterpret_cast<uintptr_t>(
nullptr)) {}
42 m_Value(from_ptr(p) | from_int(value))
45 KTL_ASSERT((
reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
55 KTL_ASSERT((
reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
59 m_Value(from_int(value))
65#ifndef KTL_EXPLICIT_POINTER
86 template<
typename Y = IntT,
typename = std::enable_if_t<!std::is_same_v<Y,
bool>, Y>>
89 template<
typename Y = IntT,
typename = std::enable_if_t<!std::is_same_v<Y,
bool>, Y>>
90 operator IntT() const noexcept {
return get_int(); }
92 explicit operator bool() const noexcept {
return get_ptr(); }
97 decltype(*std::declval<PtrT>())
operator*()
const noexcept {
return *
get_ptr(); }
99 template<
typename... Ts>
100 decltype(
auto)
operator()(Ts&&... args)
const noexcept {
return get_ptr()(std::forward<Ts>(args) ...); }
104 IntT
get_int() const noexcept {
return to_int(m_Value); }
109 KTL_ASSERT((
reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
111 m_Value = from_ptr(p) | (m_Value & INT_MASK);
119 m_Value = (m_Value & PTR_MASK) | from_int(value);
123 ptr_type to_ptr(uintptr_t value)
const noexcept
125 return reinterpret_cast<ptr_type>(value & PTR_MASK);
128 uintptr_t from_ptr(PtrT value)
const noexcept
130 return reinterpret_cast<uintptr_t
>(value) & PTR_MASK;
133 IntT to_int(uintptr_t value)
const noexcept
135 return static_cast<IntT
>(
static_cast<int_type>(value & INT_MASK) +
static_cast<int_type>(Min));
138 uintptr_t from_int(IntT value)
const noexcept
140 return static_cast<uintptr_t
>(
static_cast<int_type>(value) -
static_cast<int_type>(Min)) & 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:18
ptr_type get_ptr() const noexcept
Definition packed_ptr.h:102
IntT get_int() const noexcept
Definition packed_ptr.h:104
friend bool operator==(IntT n, packed_ptr pack) noexcept
Definition packed_ptr.h:84
friend bool operator==(packed_ptr pack, PtrT p) noexcept
Definition packed_ptr.h:78
packed_ptr(PtrT p, IntT value) noexcept
Definition packed_ptr.h:41
static constexpr uintmax_t UsedBits
Definition packed_ptr.h:23
static constexpr uintmax_t FreeBits
Definition packed_ptr.h:24
packed_ptr(PtrT p) noexcept
Definition packed_ptr.h:51
PtrT ptr_type
Definition packed_ptr.h:20
friend bool operator==(packed_ptr pack, IntT n) noexcept
Definition packed_ptr.h:80
packed_ptr() noexcept
Definition packed_ptr.h:38
friend bool operator==(PtrT p, packed_ptr pack) noexcept
Definition packed_ptr.h:82
void set_int(IntT value) noexcept
Definition packed_ptr.h:114
packed_ptr(IntT value) noexcept
Definition packed_ptr.h:58
void set_ptr(PtrT p) noexcept
Definition packed_ptr.h:106
packed_ptr & operator=(PtrT p) noexcept
Definition packed_ptr.h:66
detail::underlying_type_t< IntT > int_type
Definition packed_ptr.h:21
packed_ptr & operator=(IntT value) noexcept
Definition packed_ptr.h:72
ptr_type operator->() const noexcept
Definition packed_ptr.h:95
typename underlying_type< T >::type underlying_type_t
Definition packed_ptr_fwd.h:62
constexpr uintmax_t bits_in_range(intmax_t min, intmax_t max) noexcept
Definition bits.h:35
constexpr uintmax_t log2(uintmax_t n) noexcept
Definition bits.h:7
Definition cascading.h:16