#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 }}