6#include <userver/utils/assert.hpp>
13class TaggedPtr final {
14 static_assert(
sizeof(std::uintptr_t) <=
sizeof(std::uint64_t));
15 static constexpr std::uint64_t kTagShift = 48;
18 using Tag = std::uint16_t;
20 constexpr TaggedPtr(std::nullptr_t)
noexcept : impl_(0) {}
22 TaggedPtr(T* ptr, Tag tag)
23 : impl_(
reinterpret_cast<std::uintptr_t>(ptr) |
24 (std::uint64_t{tag} << kTagShift)) {
25 UASSERT(!(
reinterpret_cast<std::uintptr_t>(ptr) & 0xffff'0000'0000'0000));
28 T* GetDataPtr()
const noexcept {
29 return reinterpret_cast<T*>(
static_cast<std::uintptr_t>(
30 impl_ & ((std::uint64_t{1} << kTagShift) - 1)));
33 Tag GetTag()
const noexcept {
return static_cast<Tag>(impl_ >> kTagShift); }
35 Tag GetNextTag()
const noexcept {
return static_cast<Tag>(GetTag() + 1); }