#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTALLOCUTILS_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTALLOCUTILS_H #include #include namespace DetourNavigator { static_assert(sizeof(std::size_t) == sizeof(void*), ""); enum BufferType : std::size_t { BufferType_perm, BufferType_temp, BufferType_unused, }; inline BufferType* tempPtrBufferType(void* ptr) { return reinterpret_cast(static_cast(ptr) + 1); } inline BufferType getTempPtrBufferType(void* ptr) { return *tempPtrBufferType(ptr); } inline void setTempPtrBufferType(void* ptr, BufferType value) { *tempPtrBufferType(ptr) = value; } inline void** tempPtrPrev(void* ptr) { return static_cast(ptr); } inline void* getTempPtrPrev(void* ptr) { return *tempPtrPrev(ptr); } inline void setTempPtrPrev(void* ptr, void* value) { *tempPtrPrev(ptr) = value; } inline void* getTempPtrDataPtr(void* ptr) { return reinterpret_cast(static_cast(ptr) + 2); } inline BufferType* dataPtrBufferType(void* dataPtr) { return reinterpret_cast(static_cast(dataPtr) - 1); } inline BufferType getDataPtrBufferType(void* dataPtr) { return *dataPtrBufferType(dataPtr); } inline void setDataPtrBufferType(void* dataPtr, BufferType value) { *dataPtrBufferType(dataPtr) = value; } inline void* getTempDataPtrStackPtr(void* dataPtr) { return static_cast(dataPtr) - 2; } inline void* getPermDataPtrHeapPtr(void* dataPtr) { return static_cast(dataPtr) - 1; } inline void setPermPtrBufferType(void* ptr, BufferType value) { *static_cast(ptr) = value; } inline void* getPermPtrDataPtr(void* ptr) { return static_cast(ptr) + 1; } // TODO: use std::align inline void* align(std::size_t align, std::size_t size, void*& ptr, std::size_t& space) noexcept { const auto intptr = reinterpret_cast(ptr); const auto aligned = (intptr - 1u + align) & - align; const auto diff = aligned - intptr; if ((size + diff) > space) return nullptr; space -= diff; return ptr = reinterpret_cast(aligned); } } #endif