#include <type_traits>
#include <cstddef>
#include <tuple>
#include <cstdio>
template<typename...>
struct dump;
template<typename T>
struct Return { using type = T; };
struct Nil;
template <typename ...Ts>
struct TypeList {
using type = TypeList<Ts...>;
static constexpr size_t size = sizeof...(Ts);
template <typename ...T>
using append = TypeList<Ts..., T...>;
template <template<typename...> typename T>
using exportTo = T<Ts...>;
};
template<typename G>
struct Not;
template<template<typename...> class G, typename... Args>
struct Not<G<Args...>>: std::bool_constant<!G<Args...>::value> { };
template<typename IN, template <typename> class F>
struct Map;
template<typename IN, template <typename> class F>
using Map_t = typename Map<IN, F>::type;
template<template <typename> class F, typename ...Ts>
struct Map<TypeList<Ts...>, F>: TypeList<typename F<Ts>::type...> {};
template<typename IN, template <typename> class P, typename OUT = TypeList<>>
struct Filter: OUT {};
template<typename IN, template <typename> class P>
using Filter_t = typename Filter<IN, P>::type;
template<template <typename> class P, typename OUT, typename H, typename ...Ts>
struct Filter<TypeList<H, Ts...>, P, OUT>:
std::conditional_t<P<H>::value,
Filter<TypeList<Ts...>, P, typename OUT::template append<H>>,
Filter<TypeList<Ts...>, P, OUT>> { };
template<typename IN, typename INIT, template<typename, typename> class OP>
struct FoldL: Return<INIT> {};
template<typename IN, typename INIT, template<typename, typename> class OP>
using FoldL_t = typename FoldL<IN, INIT, OP>::type;
template<typename ACC, template<typename, typename> class OP,
typename H, typename ...Ts>
struct FoldL<TypeList<H, Ts...>, ACC, OP>:
FoldL<TypeList<Ts...>, typename OP<ACC, H>::type, OP> {};
template<typename IN,
template<typename> typename P,
typename S = TypeList<>,
typename R = TypeList<>>
struct Partition {
struct type {
using satisfied = S;
using rest = R;
};
};
template<typename IN, template<typename> class P>
using Partition_t = typename Partition<IN, P>::type;
template<typename H, typename ...Ts, template<typename> typename P, typename S, typename R>
struct Partition<TypeList<H, Ts...>, P, S, R>: std::conditional_t<P<H>::value,
Partition<TypeList<Ts...>, P, typename S::template append<H>, R>,
Partition<TypeList<Ts...>, P, S, typename R::template append<H>>> {};
template<typename... IN>
struct Concat;
template<typename... IN>
using Concat_t = typename Concat<IN...>::type;
template<> struct Concat<>: TypeList<> { };
template<typename IN> struct Concat<IN>: IN { };
template<typename IN, typename IN2>
struct Concat<IN, IN2>: IN2::template exportTo<IN::template append> { };
template<typename IN, typename IN2, typename ...Rest>
struct Concat<IN, IN2, Rest...>: Concat_t<Concat_t<IN, IN2>, Rest...> { };
template<typename IN>
class Flatten {
struct impl {
template<typename ACC, typename E>
struct Append: ACC::template append<E> {};
template<typename ACC, typename ...Ts>
struct Append<ACC, TypeList<Ts...>>:
Concat_t<ACC, typename Flatten<TypeList<Ts...>>::type> {};
};
template<typename ACC, typename E>
using Append = typename impl::template Append<ACC, E>;
public:
using type = FoldL_t<IN, TypeList<>, Append>;
};
template<typename IN>
using Flatten_t = typename Flatten<IN>::type;
template<typename IN, template<typename, typename> class CMP>
struct Sort: TypeList<> {};
template<typename IN, template<typename, typename> class CMP>
using Sort_t = typename Sort<IN, CMP>::type;
template<template<typename, typename> class CMP, typename H, typename ...Ts>
class Sort<TypeList<H, Ts...>, CMP> {
template<typename E> using LT = CMP<E, H>;
using P = Partition_t<TypeList<Ts...>, LT>;
using SmallerSorted = Sort_t<typename P::satisfied, CMP>;
using BiggerSorted = Sort_t<typename P::rest, CMP>;
public:
using type = Concat_t<typename SmallerSorted::template append<H>, BiggerSorted>;
};
template<typename IN, typename E>
struct Elem: std::false_type { };
template<typename IN, typename E>
constexpr bool Elem_v = Elem<IN, E>::value;
template<typename E, typename ...Ts>
struct Elem<TypeList<Ts...>, E>:
std::bool_constant<(std::is_same_v<E, Ts> || ...)> { };
template<typename IN>
class Unique {
template<typename ACC, typename E>
struct Append: std::conditional_t<Elem_v<ACC, E>,
ACC, typename ACC::template append<E>> {};
public:
using type = FoldL_t<IN, TypeList<>, Append>;
};
template<typename IN>
using Unique_t = typename Unique<IN>::type;
template<typename IN, template <typename> class F>
struct FindBy: Return<Nil> {};
template<typename IN, template <typename> class F>
using FindBy_t = typename FindBy<IN, F>::type;
template<typename H, typename ...Ts, template <typename> class F>
struct FindBy<TypeList<H, Ts...>, F>: std::conditional_t<F<H>::value,
Return<H>, FindBy<TypeList<Ts...>, F>> {};
template<typename A, typename B,
template<typename, typename> class PAIR>
struct CrossProduct;
template<typename A, typename B, template<typename, typename> class PAIR>
using CrossProduct_t = typename CrossProduct<A, B, PAIR>::type;
template<typename A, typename B, template<typename, typename> class PAIR>
class CrossProduct {
template<typename RESULT_OUTTER, typename TA>
struct OuterAppend {
template<typename RESULT_INNER, typename TB>
struct InnerAppend: RESULT_INNER::template append<PAIR<TA, TB>> { };
using type = FoldL_t<B, RESULT_OUTTER, InnerAppend>;
};
public:
using type = FoldL_t<A, TypeList<>, OuterAppend>;
};
//
// TaskDSL Implementation
template<typename J>
struct JobWrapper {
void operator()() {
return J();
}
};
template<typename LINK>
struct Connection {};
template<typename Job1, typename Job2>
struct Connection<auto(*)(Job1) -> auto(*)(Job2) -> void> {
using FROM = Job1;
using DST = Job2;
};
template <typename... LINKS>
class Task {
class JobDescendantsMap {
template<typename Con>
struct GetFrom: Return<typename Con::FROM> { };
template<typename Con>
struct GetDst: Return<typename Con::DST> { };
using Connections = Unique_t<TypeList<Connection<LINKS>...>>; // remove same edge
using FromJobs = Map_t<Connections, GetFrom>;
using DstJobs = Map_t<Connections, GetDst>;
using AllJobs = Unique_t<Concat_t<FromJobs, DstJobs>>;
template<typename J>
class FindJobDescendants {
template<typename C> struct Dependency:
std::is_same<typename GetFrom<C>::type, J> { };
using JobDescendants = Filter_t<Connections, Dependency>;
public:
struct type {
using Job = J;
using Descendants = Map_t<JobDescendants, GetDst>;
};
};
public:
using type = Map_t<AllJobs, FindJobDescendants>;
};
// [<Job, Descendants>]
using JobDescendantsMap_t = typename JobDescendantsMap::type;
class SortedJobs {
template<typename DECENDS>
class FindAllDescendants {
template<typename ACC, typename Job>
struct AppendDes {
template <typename DEP> struct JDepsCond:
std::is_same<typename DEP::Job, Job> {};
using DepsResult = FindBy_t<JobDescendantsMap_t, JDepsCond>; // 从邻接表查找Job的后继节点列表
using type = Concat_t<typename ACC::template append<Job>,
typename FindAllDescendants<typename DepsResult::Descendants>::type>;
};
public:
using type = FoldL_t<DECENDS, TypeList<>, AppendDes>;
};
template<typename DEP>
struct FindJobAllDescendants {
struct type {
using Job = typename DEP::Job;
using AllDescendants =
typename FindAllDescendants<typename DEP::Descendants>::type;
};
};
template<typename DEP> struct GetJob: Return<typename DEP::Job> { };
using JobAllDescendantsMap = Map_t<JobDescendantsMap_t, FindJobAllDescendants>;
template<typename LHS, typename RHS>
struct JobCmp: Elem<typename LHS::AllDescendants, typename RHS::Job> { };
public:
using type = Map_t<typename Sort<JobAllDescendantsMap, JobCmp>::type, GetJob>;
};
template<typename ...Jobs>
struct Runable { };
template<auto ...J>
struct Runable<JobWrapper<J>...> {
static constexpr void Run() {
return (JobWrapper<J>{}(),...);
}
};
public:
constexpr void Run() {
using Jobs = typename SortedJobs::type::template exportTo<Runable>;
return Jobs::Run();
}
};
#define __task(...) Task<__VA_ARGS__>{}
#define __job(job) auto(*) (JobWrapper<job>)
#define __link(link) link -> void
//
// TaskDSL Usecase
void Meat()
{ puts("肉..."); }
void Garnish()
{ puts("配菜..."); }
void Plating()
{ puts("装配..."); }
void Servce1()
{ puts("送菜1..."); }
void Servce2()
{ puts("送菜2..."); }
int main(int argc, char** argv) {
__task(
__link(__job(Plating) -> __job(Servce1)),
__link(__job(Meat) -> __job(Plating)),
__link(__job(Plating) -> __job(Servce2)),
__link(__job(Garnish) -> __job(Plating))).Run();
return 0;
}
C++ DSL 实现
最新推荐文章于 2024-05-24 09:32:11 发布