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); }