71 lines
2.4 KiB
C
71 lines
2.4 KiB
C
|
#ifndef ALSK_ALSK_SKELETON_BONE_SERIAL_H
|
||
|
#define ALSK_ALSK_SKELETON_BONE_SERIAL_H
|
||
|
|
||
|
#include "../bonebase.h"
|
||
|
|
||
|
namespace alsk {
|
||
|
|
||
|
template<typename, typename...> struct Serial;
|
||
|
|
||
|
template<typename Signature, typename... FunTypes, typename... LinksTypes>
|
||
|
struct Serial<Signature, tmp::Pack<FunTypes, LinksTypes>...>: SkeletonBase {
|
||
|
using Links = tmp::Pack<LinksTypes...>;
|
||
|
using PackP = tmp::Parameters<Signature>;
|
||
|
using PackR = Returns<Links>;
|
||
|
using PackX = tmp::Pack<>;
|
||
|
using Packs = arg::Placeholders<PackP, PackR, PackX>;
|
||
|
|
||
|
using TasksP = tmp::Pack<FunTypes...>;
|
||
|
using Tasks = std::tuple<FunTypes...>;
|
||
|
|
||
|
Tasks tasks;
|
||
|
|
||
|
template<std::size_t I>
|
||
|
constexpr auto const& task() const noexcept { return std::get<I>(tasks); }
|
||
|
template<std::size_t I>
|
||
|
constexpr auto& task() noexcept { return std::get<I>(tasks); }
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
struct SkeletonTraits<Serial> {
|
||
|
static constexpr bool serial = true;
|
||
|
|
||
|
template<typename Skeleton, typename F, typename T>
|
||
|
static constexpr decltype(auto) traverse(std::size_t parDepth, Skeleton&& skeleton, F&& function, T&& init) {
|
||
|
auto indices = std::make_index_sequence<std::tuple_size<decltype(skeleton.tasks)>{}>();
|
||
|
return _traverse(parDepth, std::forward<Skeleton>(skeleton), std::forward<F>(function), std::forward<T>(init), std::move(indices));
|
||
|
}
|
||
|
|
||
|
template<typename Skeleton, typename F, typename T, std::size_t... Is>
|
||
|
static constexpr decltype(auto) _traverse(std::size_t parDepth, Skeleton&& skeleton, F&& function, T&& init, std::index_sequence<Is...>) {
|
||
|
using Traversers = tmp::Pack<
|
||
|
SkeletonTraversal<std::tuple_element_t<Is, typename std::decay_t<Skeleton>::Tasks>>...
|
||
|
>;
|
||
|
return function(parDepth, skeleton, tmp::PackGet<Traversers, Is>::execute(parDepth, skeleton.template task<Is>(), function, init)...);
|
||
|
}
|
||
|
|
||
|
template<typename Skeleton>
|
||
|
static constexpr std::size_t parallelizability(Skeleton&&) noexcept {
|
||
|
return 1;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
namespace impl {
|
||
|
|
||
|
template<typename Tuple, typename F, std::size_t... indices>
|
||
|
void skeletonTraversalSerial(Tuple const& tasks, F f, std::index_sequence<indices...>) {
|
||
|
using Expander = int[];
|
||
|
static_cast<void>(Expander{(f(std::get<indices>(tasks), 1), 0)...});
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
template<typename Signature, typename... Tasks, typename F>
|
||
|
void skeletonTraversal(Serial<Signature, Tasks...> const& s, F&& f) {
|
||
|
impl::skeletonTraversalSerial(s.tasks, std::forward<F>(f), std::make_index_sequence<sizeof...(Tasks)>());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|