#pragma once #include #include namespace geode::utils { template class MiniFunction; template class MiniFunctionStateBase { public: virtual ~MiniFunctionStateBase() = default; virtual Ret call(Args... args) const = 0; virtual MiniFunctionStateBase* clone() const = 0; }; template class MiniFunctionState final : public MiniFunctionStateBase { public: Type m_func; explicit MiniFunctionState(Type func) : m_func(std::move(func)) {} Ret call(Args... args) const override { return const_cast(m_func)(args...); } MiniFunctionStateBase* clone() const override { return new MiniFunctionState(*this); } }; template class MiniFunction { public: using FunctionType = Ret(Args...); using StateType = MiniFunctionStateBase; private: StateType* m_state; public: MiniFunction() : m_state(nullptr) {} MiniFunction(MiniFunction const& other) : m_state(other.m_state ? other.m_state->clone() : nullptr) {} MiniFunction(MiniFunction&& other) : m_state(other.m_state) { other.m_state = nullptr; } ~MiniFunction() { delete m_state; } template requires requires(Callable&& func, Args... args) { { func(args...) } -> std::same_as; } MiniFunction(Callable&& func) : m_state(new MiniFunctionState, Ret, Args...>(std::forward(func))) {} MiniFunction& operator=(MiniFunction const& other) { delete m_state; m_state = other.m_state ? other.m_state->clone() : nullptr; return *this; } MiniFunction& operator=(MiniFunction&& other) { delete m_state; m_state = other.m_state; other.m_state = nullptr; return *this; } Ret operator()(Args... args) const { return m_state->call(args...); } explicit operator bool() const { return m_state; } }; }