#pragma once #include #include class CPointer { public: CPointer() { m_Value = 0; } template CPointer(T value) { m_Value = (uintptr_t)(value); } bool IsValid() const { return m_Value != 0; } template auto Get() const { return reinterpret_cast(m_Value); } template std::add_lvalue_reference_t GetField(int offset) const { return *GetFieldPtr(offset).Get(); } template auto Call(Args... args) const { if constexpr (std::is_invocable_v) { if (IsValid()) { return std::invoke(Get(), std::forward(args)...); } } else { static_assert(std::is_invocable_v, "T must be an invocable type."); } LogInvalid(); return std::invoke_result_t{}; } CPointer GetFieldPtr(int offset) const; CPointer& Offset(int offset); CPointer& Absolute(int preAbs, int postAbs); CPointer& Dereference(int count); private: void LogInvalid() const; uintptr_t m_Value; };