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