2025-07-25 21:45:33 +03:00

50 lines
1.2 KiB
C++

#pragma once
#include <cstdint>
#include <type_traits>
class CPointer {
public:
CPointer() { m_Value = 0; }
template <typename T>
CPointer(T value) {
m_Value = (uintptr_t)(value);
}
bool IsValid() const { return m_Value != 0; }
template <typename T>
auto Get() const {
return reinterpret_cast<T>(m_Value);
}
template <typename T>
std::add_lvalue_reference_t<T> GetField(int offset) const {
return *GetFieldPtr(offset).Get<T*>();
}
template <typename T, typename... Args>
auto Call(Args... args) const {
if constexpr (std::is_invocable_v<T, Args...>) {
if (IsValid()) {
return std::invoke(Get<T>(), std::forward<Args>(args)...);
}
} else {
static_assert(std::is_invocable_v<T, Args...>, "T must be an invocable type.");
}
LogInvalid();
return std::invoke_result_t<T, Args...>{};
}
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;
};