19#include "lib/stdcompat/bit.h"
20#include "pw_assert/assert.h"
40 static constexpr size_t NumBits() {
42 return 31 - cpp20::countl_zero(
static_cast<uint32_t
>(
alignof(T)));
45 constexpr explicit PackedPtr() { CheckAlignment(); }
53 template <
typename T2,
54 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
59 template <
typename T2,
60 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
66 template <
typename T2,
67 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
69 *
this = std::move(other);
72 template <
typename T2,
73 typename = std::enable_if_t<std::is_convertible_v<T2, T>>>
75 data_ = std::exchange(other.data_, 0);
79 constexpr T& operator*()
const {
return *(
get()); }
80 constexpr T* operator->()
const {
return get(); }
83 constexpr T*
get()
const {
return cpp20::bit_cast<T*>(data_ & ~kValueMask); }
86 constexpr uintptr_t
packed_value()
const {
return data_ & kValueMask; }
89 constexpr void set(T* ptr) {
90 auto packed_ptr = cpp20::bit_cast<uintptr_t, T*>(ptr);
91 PW_DASSERT((packed_ptr & kValueMask) == 0);
107 static constexpr void CheckAlignment() {
108 static_assert(
alignof(T) > 1,
109 "Alignment must be more than one to pack any bits");
112 static constexpr uintptr_t kValueMask = (1 << NumBits()) - 1;
116 friend class PackedPtr;
Definition: packed_ptr.h:35
constexpr void set_packed_value(uintptr_t packed_value)
Definition: packed_ptr.h:98
constexpr void set(T *ptr)
Sets the pointer without changing the packed value.
Definition: packed_ptr.h:89
constexpr uintptr_t packed_value() const
Returns the packed_value packed into the unused bits of the pointer.
Definition: packed_ptr.h:86
constexpr T * get() const
Returns the pointer.
Definition: packed_ptr.h:83
The Pigweed namespace.
Definition: alignment.h:27