83 lines
2.3 KiB
C
83 lines
2.3 KiB
C
|
#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
|