
#ifndef PLS_INVOKE_PARALLEL_IMPL_H
#define PLS_INVOKE_PARALLEL_IMPL_H

#include "pls/internal/scheduling/task.h"
#include "pls/internal/scheduling/lambda_task.h"
#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/thread_state.h"

namespace pls {
namespace algorithm {

template<typename Function1, typename Function2>
void invoke_parallel(const Function1 &function1, const Function2 &function2) {
  using namespace ::pls::internal::scheduling;

  auto sub_task_1 = lambda_task_by_reference<Function1>(function1);
  auto sub_task_2 = lambda_task_by_reference<Function2>(function2);

  scheduler::spawn_child(sub_task_2);
  scheduler::spawn_child_and_wait(sub_task_1);
}

template<typename Function1, typename Function2, typename Function3>
void invoke_parallel(const Function1 &function1, const Function2 &function2, const Function3 &function3) {
  using namespace ::pls::internal::scheduling;

  auto sub_task_1 = lambda_task_by_reference<Function1>(function1);
  auto sub_task_2 = lambda_task_by_reference<Function2>(function2);
  auto sub_task_3 = lambda_task_by_reference<Function3>(function3);

  scheduler::spawn_child(sub_task_3);
  scheduler::spawn_child(sub_task_2);
  scheduler::spawn_child_and_wait(sub_task_1);
}

}
}

#endif //PLS_INVOKE_PARALLEL_IMPL_H
