Last active
June 27, 2025 15:46
-
-
Save kerrytazi/8889c517367ea6ccd98d29f9265faa42 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <cstddef> | |
#include <bit> | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr TRet* poff(TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return std::bit_cast<TRet*>(std::bit_cast<char*>(ptr) + offset); | |
} | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr const TRet* poff(const TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return std::bit_cast<const TRet*>(std::bit_cast<const char*>(ptr) + offset); | |
} | |
template <typename TVal> | |
[[nodiscard]] static inline constexpr TVal* poff(TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return poff<TVal, TVal>(ptr, offset); | |
} | |
template <typename TVal> | |
[[nodiscard]] static inline constexpr const TVal* poff(const TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return poff<TVal, TVal>(ptr, offset); | |
} | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr TRet voff(const TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return *poff<TRet, TVal>(ptr, offset); | |
} | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr TRet& roff(TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return *poff<TRet, TVal>(ptr, offset); | |
} | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr const TRet& roff(const TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return *poff<TRet, TVal>(ptr, offset); | |
} | |
template <typename> | |
struct _fcast {}; | |
template <typename TRet, typename... TArgs> | |
struct _fcast<TRet(TArgs...)> | |
{ | |
using pointer = TRet(*)(TArgs...); | |
}; | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr typename _fcast<TRet>::pointer foff(TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return std::bit_cast<typename _fcast<TRet>::pointer>(poff<void, TVal>(ptr, offset)); | |
} | |
template <typename TRet, typename TVal> | |
[[nodiscard]] static inline constexpr const typename _fcast<TRet>::pointer foff(const TVal* ptr, ptrdiff_t offset = 0) | |
{ | |
return std::bit_cast<const typename _fcast<TRet>::pointer>(poff<void, TVal>(ptr, offset)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pointer_utils.hpp" | |
#include <iostream> | |
struct MyStruct | |
{ | |
int32_t a; | |
float b; | |
int64_t c; | |
}; | |
int external_func(float a, double b) | |
{ | |
return a + b; | |
} | |
void test() | |
{ | |
MyStruct s; | |
void* p = poff<void>(&s); | |
roff<int32_t>(p, 0) = 123; | |
roff<float>(p, 4) = 234.0f; | |
roff<int64_t>(p, 8) = 345; | |
std::cout << "MyStruct::a = " << voff<int32_t>(p, 0) << "\n"; | |
std::cout << "MyStruct::b = " << voff<float>(p, 4) << "\n"; | |
std::cout << "MyStruct::c = " << voff<int64_t>(p, 8) << "\n"; | |
std::cout << "MyStruct::a = " << s.a << "\n"; | |
std::cout << "MyStruct::b = " << s.b << "\n"; | |
std::cout << "MyStruct::c = " << s.c << "\n"; | |
void* func_void = &external_func; | |
auto func_typed = foff<int(float, double)>(func_void); | |
std::cout << "external_func: " << func_typed(2.0f, 4.0) << "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment