From b804d7d127647693c9b98421733ecee14db1a52e Mon Sep 17 00:00:00 2001 From: "Caisse, Michael" Date: Mon, 1 Jun 2026 15:37:50 -0700 Subject: [PATCH] perfrom flow graph dsl calculation in type space and convert to tuple as late as possible --- include/flow/dsl/flatten.hpp | 51 ++++++++++++++++++++++ include/flow/dsl/par.hpp | 71 +++++++++++++++++++++--------- include/flow/dsl/seq.hpp | 83 +++++++++++++++++++++++------------- 3 files changed, 155 insertions(+), 50 deletions(-) create mode 100644 include/flow/dsl/flatten.hpp diff --git a/include/flow/dsl/flatten.hpp b/include/flow/dsl/flatten.hpp new file mode 100644 index 00000000..569f8d63 --- /dev/null +++ b/include/flow/dsl/flatten.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +#include + +#include + +#include + +namespace flow::dsl::detail { + +template struct initials_of { + using type = boost::mp11::mp_list; +}; + +template struct finals_of { + using type = boost::mp11::mp_list; +}; + +template struct all_mentioned_of { + using type = boost::mp11::mp_list; +}; + +template struct nodes_of { + using type = + std::conditional_t, boost::mp11::mp_list<>>; +}; + +template struct edges_of { + using type = boost::mp11::mp_list<>; +}; + +template +using star_t = std::remove_cvref_t())>; + +template struct make_edge_q { + template + using fn = edge, boost::mp11::mp_second, + Cond>; +}; + +template struct to_tuple; +template struct to_tuple> { + constexpr static auto value = stdx::tuple{}; +}; +template constexpr auto to_tuple_v = to_tuple::value; + +} // namespace flow::dsl::detail diff --git a/include/flow/dsl/par.hpp b/include/flow/dsl/par.hpp index eb13fef1..f266972a 100644 --- a/include/flow/dsl/par.hpp +++ b/include/flow/dsl/par.hpp @@ -1,10 +1,13 @@ #pragma once +#include #include #include #include +#include + namespace flow::dsl { template @@ -19,38 +22,66 @@ struct par { } private: - friend constexpr auto tag_invoke(get_initials_t, par const &p) { - return stdx::tuple_cat(get_initials(p.lhs), get_initials(p.rhs)); + friend constexpr auto tag_invoke(get_initials_t, par const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_finals_t, par const &p) { - return stdx::tuple_cat(get_finals(p.lhs), get_finals(p.rhs)); + friend constexpr auto tag_invoke(get_finals_t, par const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_nodes_t, par const &p) { - if constexpr (Identity == subgraph_identity::VALUE) { - auto all_nodes = stdx::to_unsorted_set( - stdx::tuple_cat(get_all_mentioned_nodes(p.lhs), - get_all_mentioned_nodes(p.rhs))); - - return stdx::transform([](auto const &n) { return *n; }, all_nodes); - - } else { - return stdx::tuple_cat(get_nodes(p.lhs), get_nodes(p.rhs)); - } + friend constexpr auto tag_invoke(get_nodes_t, par const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_all_mentioned_nodes_t, par const &p) { - return stdx::tuple_cat(get_all_mentioned_nodes(p.lhs), - get_all_mentioned_nodes(p.rhs)); + friend constexpr auto tag_invoke(get_all_mentioned_nodes_t, par const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_edges_t, par const &p) { - return stdx::tuple_cat(get_edges(p.lhs), get_edges(p.rhs)); + friend constexpr auto tag_invoke(get_edges_t, par const &) { + return detail::to_tuple_v::type>; } }; template par(Lhs, Rhs) -> par; + +namespace detail { +template +struct initials_of> { + using type = boost::mp11::mp_append::type, + typename initials_of::type>; +}; + +template +struct finals_of> { + using type = boost::mp11::mp_append::type, + typename finals_of::type>; +}; + +template +struct all_mentioned_of> { + using type = boost::mp11::mp_append::type, + typename all_mentioned_of::type>; +}; + +template +struct nodes_of> { + using value_nodes = boost::mp11::mp_transform< + star_t, + boost::mp11::mp_unique>::type>>; + using ref_nodes = boost::mp11::mp_append::type, + typename nodes_of::type>; + using type = std::conditional_t; +}; + +template +struct edges_of> { + using type = boost::mp11::mp_append::type, + typename edges_of::type>; +}; +} // namespace detail + } // namespace flow::dsl template diff --git a/include/flow/dsl/seq.hpp b/include/flow/dsl/seq.hpp index e064f74d..00d16b61 100644 --- a/include/flow/dsl/seq.hpp +++ b/include/flow/dsl/seq.hpp @@ -1,11 +1,14 @@ #pragma once +#include #include #include #include #include +#include + namespace flow::dsl { template ::type>; } - friend constexpr auto tag_invoke(get_finals_t, seq const &s) { - return get_finals(s.rhs); + friend constexpr auto tag_invoke(get_finals_t, seq const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_nodes_t, seq const &s) { - if constexpr (Identity == subgraph_identity::VALUE) { - auto all_nodes = stdx::to_unsorted_set( - stdx::tuple_cat(get_all_mentioned_nodes(s.lhs), - get_all_mentioned_nodes(s.rhs))); - - return stdx::transform([](auto const &n) { return *n; }, all_nodes); - - } else { - return stdx::tuple_cat(get_nodes(s.lhs), get_nodes(s.rhs)); - } + friend constexpr auto tag_invoke(get_nodes_t, seq const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_all_mentioned_nodes_t, seq const &s) { - return stdx::tuple_cat(get_all_mentioned_nodes(s.lhs), - get_all_mentioned_nodes(s.rhs)); + friend constexpr auto tag_invoke(get_all_mentioned_nodes_t, seq const &) { + return detail::to_tuple_v::type>; } - friend constexpr auto tag_invoke(get_edges_t, seq const &s) { - auto is = get_initials(s.rhs); - auto fs = get_finals(s.lhs); - - return stdx::tuple_cat( - get_edges(s.lhs), get_edges(s.rhs), - transform( - [](P const &) { - return edge, - stdx::tuple_element_t<1, P>, Cond>{}; - }, - cartesian_product_copy(fs, is))); + friend constexpr auto tag_invoke(get_edges_t, seq const &) { + return detail::to_tuple_v::type>; } }; template seq(Lhs, Rhs) -> seq; +namespace detail { +template +struct initials_of> { + using type = typename initials_of::type; +}; + +template +struct finals_of> { + using type = typename finals_of::type; +}; + +template +struct all_mentioned_of> { + using type = boost::mp11::mp_append::type, + typename all_mentioned_of::type>; +}; + +template +struct nodes_of> { + using value_nodes = boost::mp11::mp_transform< + star_t, boost::mp11::mp_unique< + typename all_mentioned_of>::type>>; + using ref_nodes = boost::mp11::mp_append::type, + typename nodes_of::type>; + using type = std::conditional_t; +}; + +template +struct edges_of> { + using pairs = + boost::mp11::mp_product::type, + typename initials_of::type>; + using cross = boost::mp11::mp_transform_q, pairs>; + using type = boost::mp11::mp_append::type, + typename edges_of::type, cross>; +}; +} // namespace detail + } // namespace flow::dsl template