yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
631a4c37a
master
1// slang-relative-ptr.h 2#ifndef SLANG_RELATIVE_PTR_H 3#define SLANG_RELATIVE_PTR_H 4 5// This file implements a smart pointer type `RelativePtr<T>` 6// that, rather than storing the actual *address* of a value 7// of type `T`, stores the relative offset (in bytes) between 8// the target `T*` and the address of the `RelativePtr<T>` 9// itself. 10// 11// This kind of pointer representation can be useful when 12// implementing "memory-mappable" data structures that can 13// still conveniently represent complicated object graphs. 14 15#include "slang-basic.h" 16 17namespace Slang 18{ 19namespace detail 20{ 21struct RelativePtr32Traits 22{ 23using Offset = Int32 ; 24using UOffset = UInt32 ; 25}; 26 27struct RelativePtr64Traits 28{ 29using Offset = Int64 ; 30using UOffset = UInt64 ; 31}; 32}// namespace detail 33 34template < typename T ,typename Traits > 35struct RelativePtr 36{ 37public : 38using This = RelativePtr < T ,Traits > ; 39using Value = T ; 40using RawPtr = T * ; 41using Offset = typename Traits ::Offset ; 42using UOffset = typename Traits ::UOffset ; 43 44SLANG_FORCE_INLINE RelativePtr ()= default ; 45SLANG_FORCE_INLINE RelativePtr (RelativePtr const & ptr ) {set (ptr ); } 46SLANG_FORCE_INLINE RelativePtr (RelativePtr && ptr ) {set (ptr ); } 47SLANG_FORCE_INLINE RelativePtr (T * ptr ) {set (ptr ); } 48 49SLANG_FORCE_INLINE void operator = (RelativePtr const & ptr ) {set (ptr ); } 50SLANG_FORCE_INLINE void operator = (RelativePtr && ptr ) {set (ptr ); } 51SLANG_FORCE_INLINE void operator = (T * ptr ) {set (ptr ); } 52 53T * get ()const 54 { 55if (_offset == 0 ) 56 { 57return nullptr ; 58 } 59 60intptr_t thisAddr = intptr_t (this ); 61intptr_t targetAddr = thisAddr + intptr_t (_offset ); 62 63return (T * )(targetAddr ); 64 } 65 66void set (T * ptr ) 67 { 68if (ptr == nullptr ) 69 { 70_offset = 0 ; 71return ; 72 } 73 74intptr_t thisAddr = intptr_t (this ); 75intptr_t targetAddr = intptr_t (ptr ); 76intptr_t offsetVal = targetAddr - thisAddr ; 77 78_offset = Offset (offsetVal ); 79SLANG_ASSERT (intptr_t (_offset )== offsetVal ); 80 } 81 82SLANG_FORCE_INLINE operator T * ()const {return get (); } 83SLANG_FORCE_INLINE T * operator -> () const { return get(); } 84 85private : 86Offset _offset = 0 ; 87}; 88 89template < typename T > 90using RelativePtr32 = RelativePtr < T , detail :: RelativePtr32Traits > ; 91 92template < typename T > 93using RelativePtr64 = RelativePtr < T , detail :: RelativePtr64Traits > ; 94 95} // namespace Slang 96 97#endif