#pragma once #include "../utils/addresser.hpp" #include "Traits.hpp" #include "../loader/Log.hpp" namespace geode::modifier { /** * A helper struct that generates a static function that calls the given function. */ #define GEODE_AS_STATIC_FUNCTION(FunctionName_) \ template <class Class2, class FunctionType> \ struct AsStaticFunction_##FunctionName_ { \ template <class FunctionType2> \ struct Impl {}; \ template <class Return, class... Params> \ struct Impl<Return (*)(Params...)> { \ static Return GEODE_CDECL_CALL function(Params... params) { \ return Class2::FunctionName_(params...); \ } \ }; \ template <class Return, class Class, class... Params> \ struct Impl<Return (Class::*)(Params...)> { \ static Return GEODE_CDECL_CALL function(Class* self, Params... params) { \ auto self2 = addresser::rthunkAdjust( \ Resolve<Params...>::func(&Class2::FunctionName_), self \ ); \ return self2->Class2::FunctionName_(params...); \ } \ }; \ template <class Return, class Class, class... Params> \ struct Impl<Return (Class::*)(Params...) const> { \ static Return GEODE_CDECL_CALL function(Class const* self, Params... params) { \ auto self2 = addresser::rthunkAdjust( \ Resolve<Params...>::func(&Class2::FunctionName_), self \ ); \ return self2->Class2::FunctionName_(params...); \ } \ }; \ static constexpr auto value = &Impl<FunctionType>::function; \ }; GEODE_AS_STATIC_FUNCTION(constructor) GEODE_AS_STATIC_FUNCTION(destructor) }