You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.3 KiB
50 lines
1.3 KiB
4 weeks ago
|
#pragma once
|
||
|
|
||
|
template <typename T, size_t bits_to_store>
|
||
|
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 | is_marked()); }
|
||
|
|
||
|
void set_mark(size_t mark) { ptr = (T*)((size_t)ptr | (mark & mask)); }
|
||
|
|
||
|
operator T*() const { return get_ptr(); }
|
||
|
|
||
|
operator size_t() const { return get_mark(); }
|
||
|
|
||
|
protected:
|
||
|
T* ptr{nullptr};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct marked_ptr<T, 1> {
|
||
|
// 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(); }
|
||
|
|
||
|
protected:
|
||
|
T* ptr{nullptr};
|
||
|
};
|