KTL
packed_ptr.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../utility/assert.h"
4 #include "../utility/bits.h"
5 #include "packed_ptr_fwd.h"
6 
7 #include <type_traits>
8 
9 namespace ktl
10 {
15  template<typename PtrT, size_t Bits, size_t Alignment>
16  class packed_ptr
17  {
18  public:
19  static constexpr uintmax_t FREE_BITS = detail::log2(Alignment);
20 
21  private:
22  static_assert(Bits <= FREE_BITS, "The number of bits in use cannot surpass the number of free bits");
23 
24  static constexpr uintptr_t INT_MASK = ((1ULL << Bits) - 1);
25  static constexpr uintptr_t PTR_MASK = ~((1ULL << FREE_BITS) - 1);
26 
27  public:
28  packed_ptr() noexcept :
29  m_Value(reinterpret_cast<uintptr_t>(nullptr)) {}
30 
31  template<typename Int>
32  explicit packed_ptr(PtrT p, Int value) noexcept :
33  m_Value((reinterpret_cast<uintptr_t>(p) & PTR_MASK) | (static_cast<uintptr_t>(value) & INT_MASK))
34  {
35  static_assert(std::is_unsigned_v<Int>, "Packed integer must be unsigned");
36 
37  // Pointer must be correctly aligned
38  KTL_ASSERT((reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
39  }
40 
41  explicit operator bool() const noexcept { return m_Value; }
42 
43  PtrT get_ptr() const noexcept { return reinterpret_cast<PtrT>(m_Value & PTR_MASK); }
44 
45  template<typename Int>
46  Int get_int() const noexcept
47  {
48  static_assert(std::is_unsigned_v<Int>, "Packed integer must be unsigned");
49 
50  return static_cast<Int>(m_Value & INT_MASK);
51  }
52 
53  void set_ptr(PtrT p) noexcept
54  {
55  // Pointer must be correctly aligned
56  KTL_ASSERT((reinterpret_cast<size_t>(p) & (Alignment - 1)) == 0);
57 
58  m_Value = (reinterpret_cast<uintptr_t>(p) & PTR_MASK) | (m_Value & INT_MASK);
59  }
60 
61  template<typename Int>
62  void set_int(Int value) noexcept
63  {
64  static_assert(std::is_unsigned_v<Int>, "Packed integer must be unsigned");
65 
66  m_Value = (m_Value & PTR_MASK) | (static_cast<uintptr_t>(value) & INT_MASK);
67  }
68 
69  private:
70  uintptr_t m_Value;
71  };
72 }
#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