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.
		
		
		
		
		
			
		
			
				
					
					
						
							63 lines
						
					
					
						
							1.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							63 lines
						
					
					
						
							1.7 KiB
						
					
					
				
								#pragma once
							 | 
						|
								
							 | 
						|
								#include <cstddef>
							 | 
						|
								
							 | 
						|
								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 | 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 <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(); }
							 | 
						|
								
							 | 
						|
								//     T* operator->() const { return get_ptr(); }
							 | 
						|
								
							 | 
						|
								// protected:
							 | 
						|
								//     T* ptr{nullptr};
							 | 
						|
								// };
							 | 
						|
								
							 | 
						|
								template <typename F, typename T, size_t bits_to_store>
							 | 
						|
								inline static marked_ptr<F, bits_to_store> static_pointer_cast(const marked_ptr<T, bits_to_store>& p)
							 | 
						|
								{
							 | 
						|
								    return marked_ptr<F, bits_to_store>(static_cast<F*>(p.get_ptr()), p.get_mark());
							 | 
						|
								}
							 |