#pragma once #include "../utils/addresser.hpp" #include "Traits.hpp" #define GEODE_WRAPPER_FOR_IDENTIFIER(identifier) \ /* Default - function Return Class::identifier(Parameters...) does not exist */ \ template \ struct identifier { \ public: \ constexpr static inline auto value = nullptr; \ constexpr static inline auto uuid = nullptr; \ }; \ /* Specialization - function Return Class::identifier(Parameters...) is a member function */ \ template \ struct identifier< \ Class, Return(Parameters...), \ std::enable_if_t(&Class::identifier))>>> { \ private: \ static Return wrapperImpl(Class* self, Parameters... ps) { \ self = addresser::rthunkAdjust( \ substitute(&Class::identifier), self \ ); \ return self->Class::identifier(ps...); \ } \ \ public: \ constexpr static inline auto value = &wrapperImpl; \ constexpr static inline auto uuid = \ FunctionUUID(&Class::identifier)>::value; \ }; \ /* Specialization - function Return Class::identifier(Parameters...) is a static function */ \ template \ struct identifier< \ Class, Return(Parameters...), \ std::enable_if_t< \ std::is_pointer_v(&Class::identifier))>>> { \ private: \ static Return wrapperImpl(Parameters... ps) { \ return Class::identifier(ps...); \ } \ \ public: \ constexpr static inline auto value = &wrapperImpl; \ constexpr static inline auto uuid = \ FunctionUUID(&Class::identifier)>::value; \ }; namespace geode::modifier { namespace wrap { GEODE_WRAPPER_FOR_IDENTIFIER(constructor) GEODE_WRAPPER_FOR_IDENTIFIER(destructor) }; // template class Identifier, class Base, class Derived, // class ...Types> struct PotentiallyWrongIdentifier { // template // static std::true_type existsImpl(...); // template ::uuid == nullptr || // Identifier::uuid == Identifier::uuid // )) // >> // static std::false_type existsImpl(char); // template ::uuid != nullptr && // Identifier::uuid == Identifier::uuid // )) // >> // static std::false_type existsImpl(int); // static constexpr bool value = decltype(existsImpl(0))::value; // }; }