#ifndef ALSK_ALSK_IMPL_EXECUTE_H #define ALSK_ALSK_IMPL_EXECUTE_H #include "../skeleton/utility.h" #include "../executor/traits.h" namespace alsk { namespace impl { /** * @brief internal implement function * @param executor an instance of the selected executor * @param skeleton an instance of the skeleton to implement * @param state the shared state * @param id the task identifier * @param eInfo information provided by the executor */ template< typename Executor, typename S, typename State, typename CtxId, typename ExecutorInfo, std::enable_if_t>* = nullptr, std::enable_if_t>* = nullptr > auto implement(Executor& executor, S&& skeleton, State&& state, CtxId&& id, ExecutorInfo&& eInfo) { using ImplType = Impl, typename Executor::Tag, Executor&, std::remove_reference_t>; auto impl = ImplType{std::forward(skeleton), executor, std::forward(state)}; impl.id = std::forward(id); impl.executorInfo = std::forward(eInfo); return impl; } /** * @brief internal implement function for end muscles * @param executor ignored * @param value a muscle * @param state ignored * @param id ignored * @param eInfo ignored */ template>* = nullptr, std::enable_if_t>* = nullptr > decltype(auto) implement(Executor&, T&& value, State&&, CtxId&&, ExecutorInfo&&) { return std::forward(value); } } /** * Execute */ namespace impl { template struct Execute {}; template struct Execute { template< typename Impl, typename Task, typename CtxId, typename ExecutorInfo, typename P, typename R, typename... Args > static decltype(auto) execute(Impl& impl, Task&& task, CtxId&& cid, ExecutorInfo&& eInfo, P&& p, R&& r, Args&&... args) { auto id = impl.id + std::forward(cid) * impl.skeleton.step; typename Impl::State& state = impl.state; return executeF( impl::implement(impl.executor, std::forward(task), state, id, std::forward(eInfo)), std::forward

(p), std::forward(r), state.context.args(impl.executor.contextId(impl, id)), std::forward(args)... ); } private: template< typename F, typename P, typename R, typename C, typename... Args, typename Result = tmp::invoke_result_t< std::decay_t, Args..., ArgType>... >, std::enable_if_t::value>* = nullptr > static Result executeF(F&& f, P&& p, R&& r, C&& c, Args&&... args) { return std::forward(f)( std::forward(args)..., ArgGet::get(std::forward

(p), std::forward(r), std::forward(c))... ); } template< typename F, typename P, typename R, typename C, typename... Args, typename Result = tmp::invoke_result_t< std::decay_t, Args..., ArgType>... >, std::enable_if_t::value>* = nullptr > static auto executeF(F&& f, P&& p, R&& r, C&& c, Args&&... args) { std::forward(f)( std::forward(args)..., ArgGet::get(std::forward

(p), std::forward(r), std::forward(c))... ); return tmp::Void{}; } }; } template using Execute = impl::Execute>; } #endif