• Functional.h
  • #pragma once
    #include <functional>
    #include <tuple>
    #include <type_traits>
    #include <utility>
    
    template <typename ReturnType, typename... Args> class FunctionWrapper {
    private:
        std::function<ReturnType(Args...)> fp;
        std::tuple<Args...> args;
    
        template <std::size_t... Is> 
        ReturnType callFunc(std::index_sequence<Is...>) {
            if constexpr (std::is_same_v<void, ReturnType>) {
                fp(std::get<Is>(args)...);
                return; 
            } else {
                return fp(std::get<Is>(args)...);
            }
        }
    
    public:
        FunctionWrapper(ReturnType (*fp)(Args...), Args &&...a) : args(a...), fp(fp) {}
        ReturnType Invoke() {
            if constexpr (std::is_same_v<void, ReturnType>) {
                callFunc(std::index_sequence_for<Args...>());
                return; 
            }
            return callFunc(std::index_sequence_for<Args...>());
        }
        ReturnType operator()() {
            if constexpr (std::is_same_v<void, ReturnType>) {
                Invoke();
                return;
            }
            return Invoke();
        }
        operator ReturnType() { return Invoke(); }
    };