#ifndef ALSK_ALSK_SKELETON_UTILITY_H #define ALSK_ALSK_SKELETON_UTILITY_H #include #include #include "link/link.h" #include "struct/struct.h" #include "muscle/muscle.h" #include "traits.h" namespace alsk { namespace impl { /** * Build inner skeletons */ template struct BuildSkeletonParts; template< template class Skel, typename... Ss, typename R, typename... Params, typename... Ls, typename PParams, typename RParams, typename XParams > struct BuildSkeletonParts, alsk::L, PParams, RParams, XParams> { using Placeholders = arg::Placeholders; using prms = tmp::Pack...>; using rets = typename LinksToReturnTypes::type; using xprm = tmp::Pack<>; using type = alsk::Fun< Skel< R(RealType...), typename BuildSkeletonParts::type... >, RealType, rets, xprm>>(Params...) >; }; template struct BuildSkeletonParts { using type = alsk::Fun; }; /** * Build outer skeleton */ template struct BuildSkeleton; template class Skel, typename... Ss, typename R, typename... Params, typename... Ls> struct BuildSkeleton, alsk::L> { using rets = typename LinksToReturnTypes::type; using xprm = tmp::Pack<>; using type = Skel< R(Params...), typename BuildSkeletonParts, rets, xprm>::type... >; }; } /** * Build a skeleton from its structure and its links */ template using BuildSkeletonT = typename impl::BuildSkeleton::type; template class S, template class L> struct BuildSkeleton { template struct Type; template struct Type, tmp::Pack> { using type = BuildSkeletonT, L>; }; template using type = typename Type::type; template using skeleton = typename Type::type; }; // is it possible? // template class S, template class L> // template // using type = typename BuildSkeleton::type; template class Skeleton, typename S, typename L = S> struct Branch { template using skeleton = Skeleton; using signature = S; using links = L; }; template struct Leaf { using type = T; using links = L; }; /** * TreeFromSkeleton */ template struct TreeFromSkeletonImpl; template class Skeleton, typename S, typename... Ps> struct TreeFromSkeletonImpl, std::enable_if_t>>> { using type = tmp::Tree, typename TreeFromSkeletonImpl::type...>; }; template class Skeleton, typename S, typename... Ps, typename L> struct TreeFromSkeletonImpl, L>, std::enable_if_t>>> { using type = tmp::Tree, typename TreeFromSkeletonImpl::type...>; }; template struct TreeFromSkeletonImpl, std::enable_if_t>> { using type = tmp::Tree>; }; template using TreeFromSkeleton = typename TreeFromSkeletonImpl::type; /** * SkeletonFromTree */ template struct SkeletonFromTreeImpl; template class Skeleton, typename S, typename L, typename... Cs> struct SkeletonFromTreeImpl, Cs...>> { using type = Skeleton::fun...>; using fun = Fun; }; template struct SkeletonFromTreeImpl, Cs...>> { using type = T; using fun = Fun; }; template using SkeletonFromTree = typename SkeletonFromTreeImpl::type; /** * */ template struct GetTemplate; template class TT, typename... Ps> struct GetTemplate> { template using tmpl = TT; }; template class Skel, typename... Skargs> struct SkeletonTraversal, std::enable_if_t>>> { template static decltype(auto) execute(std::size_t parDepth, Skeleton&& skeleton, F&& function, T&& init) { using Traits = SkeletonTraits; return Traits::traverse(parDepth, std::forward(skeleton), std::forward(function), std::forward(init)); } template static decltype(auto) execute(Skeleton&& skeleton, F&& function, T&& init) { using Traits = SkeletonTraits; return Traits::traverse(0, std::forward(skeleton), std::forward(function), std::forward(init)); } }; template struct SkeletonTraversal>> { template static T execute(std::size_t, Skeleton&&, F&&, T&& init) { return init; } template static T execute(Skeleton&&, F&&, T&& init) { return init; } }; } namespace alsk { /* template struct SkeletonParallelHeightImpl { template struct CheckParallelityImpl; template class Skel, typename Sign, typename Link> struct CheckParallelityImpl> { using type = std::integral_constant::serial>; }; template struct CheckParallelityImpl> { using type = std::integral_constant; }; template using CheckParallelity = typename CheckParallelityImpl

::type; template using CheckParallelityEach = tmp::Transform; template using Sum = std::integral_constant; template using SumEach = tmp::Accumulate>; template using Max = std::integral_constantRHS::value)? LHS::value:RHS::value>; using tree = TreeFromSkeleton; using rtlpaths = tmp::TreeAllRTLPaths; using parallel = tmp::Transform; using parallelc = tmp::Transform; using result = tmp::Accumulate>; static constexpr tmp::Depth value = result::value; }; /*/ template struct SkeletonParallelHeightImpl { template struct CalcHeightImpl; template class Skel, typename Sign, typename Link, typename... Ts> struct CalcHeightImpl, Ts...> { static constexpr tmp::Depth par = SkeletonTraits::serial? 0:1; using type = std::integral_constant>; }; template struct CalcHeightImpl, Ts...> { using type = std::integral_constant; }; template using CalcHeight = typename CalcHeightImpl::type; using CalcHeightDefault = std::integral_constant; using tree = TreeFromSkeleton; static constexpr tmp::Depth value = tmp::TreeAccumulate::value; }; //*/ template constexpr tmp::Depth skeletonParallelHeight = SkeletonParallelHeightImpl::value; } #endif