rosa/inc/alsk/impl/bone/serial.h

83 lines
2.3 KiB
C
Raw Normal View History

2021-05-10 16:14:24 +00:00
#ifndef ALSK_ALSK_IMPL_BONE_SERIAL_H
#define ALSK_ALSK_IMPL_BONE_SERIAL_H
#include "../boneimplbase.h"
#include "../../skeleton/bone/serial.h"
namespace alsk {
/**
* @brief Serial implementation for any execution
*/
template<typename R, typename... Args, typename... Tasks, typename Tag, typename Executor, typename State>
struct Impl<Serial<R(Args...), Tasks...>, Tag, Executor, State>:
BoneImplBase<Serial<R(Args...), Tasks...>, Tag, Executor, State>
{
using This = Impl;
using Results = tmp::Repack<std::tuple, tmp::PackReplace<typename This::Skeleton::PackR, void, tmp::Void>>;
typename This::Skeleton skeleton;
typename This::Executor executor;
typename This::StateRef state;
Results results;
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}
{}
// out-of-class definition to silence -Winline
~Impl() noexcept;
// TODO: what happens with rvalue references?
constexpr typename This::Return operator()(Args... args) {
return serial(std::forward_as_tuple(args...));
}
private:
template<typename TupleP>
constexpr decltype(auto) serial(TupleP&& p) {
serial<0, typename This::Skeleton::Links>(skeleton.tasks, p);
return ArgGet<R>::get(std::tuple<>{}, std::move(results), std::tuple<>{});
}
/**
* execute
*/
template<
std::size_t I, typename LinksPack, typename TupleTasks,
typename TupleP,
std::enable_if_t<(I < std::tuple_size<std::decay_t<TupleTasks>>::value)>* = nullptr
>
constexpr void serial(TupleTasks& tasks, TupleP& p) {
using Task = Execute<tmp::PackHead<LinksPack>>;
std::get<I>(results) = executor.template execute<Task>(
*this, std::get<I>(tasks), p, results
);
serial<I+1, tmp::PackTrail<LinksPack>>(tasks, p);
}
/**
* recursion terminaison
*/
template<
std::size_t I, typename LinksPack, typename TupleTasks,
typename TupleP,
std::enable_if_t<(I == std::tuple_size<std::decay_t<TupleTasks>>::value)>* = nullptr
>
constexpr void serial(TupleTasks&&, TupleP&&) noexcept {}
};
// out-of-class definition to silence -Winline
template<typename R, typename... Args, typename... Tasks, typename Tag, typename Executor, typename State>
Impl<Serial<R(Args...), Tasks...>, Tag, Executor, State>::~Impl() noexcept {}
}
#endif