66 lines
1.9 KiB
C++
66 lines
1.9 KiB
C++
#define {{ BUILDING_SYMBOLS_GUARD }}
|
|
#include "{{ headerPath }}"
|
|
|
|
// Global Instance
|
|
template <unsigned int id, typename Ret, typename... Args>
|
|
__Function<id, Ret(Args...)> *__Function<id, Ret(Args...)>::instance;
|
|
|
|
// Normal Function Information
|
|
template <typename Ret, typename... Args>
|
|
class __NormalFunctionInfo final : public __FunctionInfo<Ret, Args...> {
|
|
typedef Ret (*type)(Args...);
|
|
type func;
|
|
public:
|
|
// Constructor
|
|
explicit __NormalFunctionInfo(const type func_):
|
|
func(func_) {}
|
|
// Functions
|
|
[[nodiscard]] bool can_overwrite() const override {
|
|
return true;
|
|
}
|
|
[[nodiscard]] type get() const override {
|
|
return func;
|
|
}
|
|
[[nodiscard]] type *get_addr() const override {
|
|
return nullptr;
|
|
}
|
|
void update(const type new_func) override {
|
|
func = new_func;
|
|
}
|
|
};
|
|
|
|
// Virtual Function Information
|
|
template <typename Ret, typename... Args>
|
|
class __VirtualFunctionInfo final : public __FunctionInfo<Ret, Args...> {
|
|
typedef Ret (*type)(Args...);
|
|
type *const addr;
|
|
void *const parent;
|
|
public:
|
|
// Constructor
|
|
__VirtualFunctionInfo(type *const addr_, void *const parent_):
|
|
addr(addr_),
|
|
parent(parent_) {}
|
|
// Functions
|
|
[[nodiscard]] bool can_overwrite() const override {
|
|
// If this function's address matches its parent's,
|
|
// then it was just inherited and does not actually exist.
|
|
// Overwriting this function would also overwrite its parent
|
|
// which would cause undesired behavior.
|
|
return get() != parent;
|
|
}
|
|
[[nodiscard]] type get() const override {
|
|
return *get_addr();
|
|
}
|
|
[[nodiscard]] type *get_addr() const override {
|
|
return addr;
|
|
}
|
|
void update(const type new_func) override {
|
|
// Address Should Have Already Been Updated
|
|
if (get() != new_func) {
|
|
__builtin_trap();
|
|
}
|
|
}
|
|
};
|
|
#undef super
|
|
|
|
{{ main }} |