• Fork.h
  • #pragma once
    #include <any>
    #include <iostream>
    #include <type_traits>
    #include <unistd.h>
    #include <wait.h>
    #include "Functional.h"
    
    class Fork {
    private:
      pid_t pid;
    
    public:
        Fork() {}
        template <typename ReturnType1, typename... Args1, typename ReturnType2, typename... Args2>
        void Invoke(FunctionWrapper<ReturnType1, Args1...> main, FunctionWrapper<ReturnType2, Args2...> child) {
            pid = fork();
            
            std::any res;
            if (pid == -1) {
                std::cerr << "Fork error" << std::endl;
            } else if (pid == 0) {
                child();
                exit(1);
            } else {
                if constexpr(!std::is_same<ReturnType1, void>::value)
                    res = main();
                main();
            }
            if constexpr (!std::is_same<ReturnType1, void>::value) {
                return std::any_cast<ReturnType1>(res);
            }
        }
    
        template<typename ReturnType, typename... Args>
        void Invoke(FunctionWrapper<ReturnType, Args...> child) {
            pid = fork();
            if (pid == -1) {
                std::cerr << "Fork error" << std::endl;
            } else if (pid == 0) {
                child();
                exit(1);
            }
        }
    
        template <typename ReturnType1, typename... Args1, typename ReturnType2, typename... Args2>
        ReturnType1 operator()(FunctionWrapper<ReturnType1, Args1...> main, FunctionWrapper<ReturnType2, Args2...> child) {
            Invoke(main, child); 
        }
    
        template<typename ReturnType, typename... Args>
        void operator()(FunctionWrapper<ReturnType, Args...> child) {
            Invoke(child);
        }
    
    
    };