rosa/inc/alsk/impl/bone/itersel.h
2021-05-10 18:14:24 +02:00

58 lines
1.6 KiB
C++

#ifndef ALSK_ALSK_IMPL_BONE_ITERSEL_H
#define ALSK_ALSK_IMPL_BONE_ITERSEL_H
#include <cmath>
#include <thread>
#include <vector>
#include "../boneimplbase.h"
#include "../../skeleton/bone/itersel.h"
namespace alsk {
/**
* @brief IterSel implementation for any execution
*/
template<typename R, typename... Args, typename... Tasks, typename Tag, typename Executor, typename State>
struct Impl<IterSel<R(Args...), Tasks...>, Tag, Executor, State>:
BoneImplBase<IterSel<R(Args...), Tasks...>, Tag, Executor, State>
{
using This = Impl;
using Task = Execute<typename This::Skeleton::TaskLinks>;
using Select = Execute<typename This::Skeleton::SelectLinks>;
typename This::Skeleton skeleton;
typename This::Executor executor;
typename This::StateRef state;
constexpr Impl() = default;
template<typename S, typename O>
constexpr Impl(S&& skeleton, O&& executor, State& state):
skeleton{std::forward<S>(skeleton)},
executor{std::forward<O>(executor)},
state{state}
{}
// TODO check repeatability with tag::Parallel
constexpr typename This::Return operator()(Args... args) {
using Value = typename This::Return;
auto tupleP = std::forward_as_tuple(args...);
Value best = ArgGet<arg::P<0>>::get(tupleP, std::tuple<>{}, std::tuple<>{});
for(std::size_t i = 0; i < skeleton.n; ++i) {
Value current = executor.template execute<Task>(*this, skeleton.task, tupleP, std::tuple<>{}, best);
best = executor.template execute<Select>(
*this, skeleton.select, tupleP, std::tuple<>{}, std::move(current), std::move(best)
);
}
return best;
}
};
}
#endif