#pragma once #include template struct marked_ptr { static constexpr size_t mask = (1 << bits_to_store) - 1; // static_assert(alignof(T) >= (1 << bits_to_store)); marked_ptr(T* ptr = nullptr) : ptr(ptr) {} marked_ptr(T* ptr, size_t mark) : ptr((T*)((size_t)ptr | (mark & mask))) {} T* get_ptr() const { return (T*)((size_t)ptr & ~1); } size_t get_mark() const { return (size_t)ptr & mask; } void set_ptr(T* ptr) { this->ptr = (T*)((size_t)ptr | get_mark()); } void set_mark(size_t mark) { ptr = (T*)(((size_t)ptr & ~mask) | (mark & mask)); } operator T*() const { return get_ptr(); } operator size_t() const { return get_mark(); } T* operator->() const noexcept { return get_ptr(); } protected: T* ptr{nullptr}; }; // template // struct marked_ptr { // // static_assert(alignof(T) >= 1); // marked_ptr(T* ptr = nullptr) : ptr(ptr) {} // marked_ptr(T* ptr, bool mark) : ptr((T*)((size_t)ptr | mark)) {} // T* get_ptr() const { return (T*)((size_t)ptr & ~1); } // bool is_marked() const { return (size_t)ptr & 1; } // void set_ptr(T* ptr) { this->ptr = (T*)((size_t)ptr | is_marked()); } // void set_mark(bool mark) { ptr = (T*)((size_t)ptr | mark); } // operator T*() const { return get_ptr(); } // operator bool() const { return is_marked(); } // T* operator->() const { return get_ptr(); } // protected: // T* ptr{nullptr}; // }; template inline static marked_ptr static_pointer_cast(const marked_ptr& p) { return marked_ptr(static_cast(p.get_ptr()), p.get_mark()); }