19#include "lib/stdcompat/bit.h"
20#include "pw_assert/assert.h"
38 static constexpr size_t NumBits() {
40 return 31 - cpp20::countl_zero(
static_cast<uint32_t
>(
alignof(T)));
43 constexpr explicit PackedPtr() { CheckAlignment(); }
51 template <
typename T2,
52 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
57 template <
typename T2,
58 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
64 template <
typename T2,
65 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
67 *
this = std::move(other);
70 template <
typename T2,
71 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
73 data_ = std::exchange(other.data_, 0);
77 constexpr T& operator*()
const {
return *(
get()); }
78 constexpr T* operator->()
const {
return get(); }
81 constexpr T*
get()
const {
return cpp20::bit_cast<T*>(data_ & ~kValueMask); }
84 constexpr uintptr_t
packed_value()
const {
return data_ & kValueMask; }
87 constexpr void set(T* ptr) {
88 auto packed_ptr = cpp20::bit_cast<uintptr_t, T*>(ptr);
89 PW_DASSERT((packed_ptr & kValueMask) == 0);
105 static constexpr void CheckAlignment() {
106 static_assert(
alignof(T) > 1,
107 "Alignment must be more than one to pack any bits");
110 static constexpr uintptr_t kValueMask = (1 << NumBits()) - 1;
114 friend class PackedPtr;
Definition: packed_ptr.h:33
constexpr void set_packed_value(uintptr_t packed_value)
Definition: packed_ptr.h:96
constexpr void set(T *ptr)
Sets the pointer without changing the packed value.
Definition: packed_ptr.h:87
constexpr uintptr_t packed_value() const
Returns the packed_value packed into the unused bits of the pointer.
Definition: packed_ptr.h:84
constexpr T * get() const
Returns the pointer.
Definition: packed_ptr.h:81
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27