C++ DSL 实现


#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值