Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions include/flow/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@
#include <stdx/tuple_algorithms.hpp>
#include <stdx/type_traits.hpp>

#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>

#include <utility>

namespace flow {
template <typename Renderer, flow::dsl::subgraph... Fragments>
class builder_for {
template <typename Tag>
friend constexpr auto tag_invoke(Tag, builder_for const &b) {
return b.fragments.apply([](auto const &...frags) {
return stdx::tuple_cat(Tag{}(frags)...);
});
}

public:
using interface_t = typename Renderer::interface_t;
constexpr static auto name = Renderer::name;
Expand All @@ -39,9 +35,38 @@ class builder_for {
return Renderer::template render<BuilderValue, Nexus>();
}

using is_builder = void;
stdx::tuple<Fragments...> fragments;
};

template <stdx::ct_string Name = "", typename LogPolicy = log_policy_t<Name>>
using builder = builder_for<graph_builder<Name, LogPolicy>>;
} // namespace flow

namespace flow::dsl::detail {
// Builders aggregate parts. Just expand all of the parts.
template <typename R, typename... Fs>
struct initials_of<flow::builder_for<R, Fs...>> {
using type = boost::mp11::mp_append<initials_of_t<Fs>...>;
};

template <typename R, typename... Fs>
struct finals_of<flow::builder_for<R, Fs...>> {
using type = boost::mp11::mp_append<finals_of_t<Fs>...>;
};

template <typename R, typename... Fs>
struct all_mentioned_of<flow::builder_for<R, Fs...>> {
using type = boost::mp11::mp_append<all_mentioned_of_t<Fs>...>;
};

template <typename R, typename... Fs>
struct nodes_of<flow::builder_for<R, Fs...>> {
using type = boost::mp11::mp_append<nodes_of_t<Fs>...>;
};

template <typename R, typename... Fs>
struct edges_of<flow::builder_for<R, Fs...>> {
using type = boost::mp11::mp_append<edges_of_t<Fs>...>;
};
} // namespace flow::dsl::detail
59 changes: 33 additions & 26 deletions include/flow/dsl/par.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#include <flow/dsl/subgraph_identity.hpp>
#include <flow/dsl/walk.hpp>

#include <stdx/tuple_algorithms.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>

namespace flow::dsl {
template <subgraph Lhs, subgraph Rhs,
Expand All @@ -13,44 +14,50 @@ struct par {
[[no_unique_address]] Rhs rhs;

using is_subgraph = void;
using is_composite = void;

constexpr auto operator*() const {
return par<Lhs, Rhs, subgraph_identity::VALUE>{Lhs{}, Rhs{}};
}
};

private:
friend constexpr auto tag_invoke(get_initials_t, par const &p) {
return stdx::tuple_cat(get_initials(p.lhs), get_initials(p.rhs));
}
template <subgraph Lhs, subgraph Rhs> par(Lhs, Rhs) -> par<Lhs, Rhs>;

friend constexpr auto tag_invoke(get_finals_t, par const &p) {
return stdx::tuple_cat(get_finals(p.lhs), get_finals(p.rhs));
}
namespace detail {
template <typename L, typename R, subgraph_identity I>
struct initials_of<par<L, R, I>> {
using type = boost::mp11::mp_append<initials_of_t<L>, initials_of_t<R>>;
};

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)));
template <typename L, typename R, subgraph_identity I>
struct finals_of<par<L, R, I>> {
using type = boost::mp11::mp_append<finals_of_t<L>, finals_of_t<R>>;
};

return stdx::transform([](auto const &n) { return *n; }, all_nodes);
template <typename L, typename R, subgraph_identity I>
struct all_mentioned_of<par<L, R, I>> {
using type =
boost::mp11::mp_append<all_mentioned_of_t<L>, all_mentioned_of_t<R>>;
};

} else {
return stdx::tuple_cat(get_nodes(p.lhs), get_nodes(p.rhs));
}
}
template <typename L, typename R>
struct nodes_of<par<L, R, subgraph_identity::VALUE>> {
using type = boost::mp11::mp_transform<
star_t, boost::mp11::mp_unique<
all_mentioned_of_t<par<L, R, subgraph_identity::VALUE>>>>;
};

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));
}
template <typename L, typename R>
struct nodes_of<par<L, R, subgraph_identity::REFERENCE>> {
using type = boost::mp11::mp_append<nodes_of_t<L>, nodes_of_t<R>>;
};

friend constexpr auto tag_invoke(get_edges_t, par const &p) {
return stdx::tuple_cat(get_edges(p.lhs), get_edges(p.rhs));
}
template <typename L, typename R, subgraph_identity I>
struct edges_of<par<L, R, I>> {
using type = boost::mp11::mp_append<edges_of_t<L>, edges_of_t<R>>;
};
} // namespace detail

template <subgraph Lhs, subgraph Rhs> par(Lhs, Rhs) -> par<Lhs, Rhs>;
} // namespace flow::dsl

template <flow::dsl::subgraph Lhs, flow::dsl::subgraph Rhs>
Expand Down
73 changes: 36 additions & 37 deletions include/flow/dsl/seq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#include <flow/dsl/walk.hpp>
#include <nexus/detail/runtime_conditional.hpp>

#include <stdx/tuple_algorithms.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>

namespace flow::dsl {
template <subgraph Lhs, subgraph Rhs,
Expand All @@ -15,54 +16,52 @@ struct seq {
[[no_unique_address]] Rhs rhs;

using is_subgraph = void;
using is_composite = void;

constexpr auto operator*() const {
return seq<Lhs, Rhs, subgraph_identity::VALUE, Cond>{Lhs{}, Rhs{}};
}
};

private:
friend constexpr auto tag_invoke(get_initials_t, seq const &s) {
return get_initials(s.lhs);
}

friend constexpr auto tag_invoke(get_finals_t, seq const &s) {
return get_finals(s.rhs);
}
template <subgraph Lhs, subgraph Rhs> seq(Lhs, Rhs) -> seq<Lhs, Rhs>;

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)));
namespace detail {
template <typename L, typename R, subgraph_identity I, typename C>
struct initials_of<seq<L, R, I, C>> {
using type = typename initials_of<L>::type;
};

return stdx::transform([](auto const &n) { return *n; }, all_nodes);
template <typename L, typename R, subgraph_identity I, typename C>
struct finals_of<seq<L, R, I, C>> {
using type = typename finals_of<R>::type;
};

} else {
return stdx::tuple_cat(get_nodes(s.lhs), get_nodes(s.rhs));
}
}
template <typename L, typename R, subgraph_identity I, typename C>
struct all_mentioned_of<seq<L, R, I, C>> {
using type =
boost::mp11::mp_append<all_mentioned_of_t<L>, all_mentioned_of_t<R>>;
};

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));
}
template <typename L, typename R, typename C>
struct nodes_of<seq<L, R, subgraph_identity::VALUE, C>> {
using type =
boost::mp11::mp_transform<star_t,
boost::mp11::mp_unique<all_mentioned_of_t<
seq<L, R, subgraph_identity::VALUE, C>>>>;
};

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(
[]<typename P>(P const &) {
return edge<stdx::tuple_element_t<0, P>,
stdx::tuple_element_t<1, P>, Cond>{};
},
cartesian_product_copy(fs, is)));
}
template <typename L, typename R, typename C>
struct nodes_of<seq<L, R, subgraph_identity::REFERENCE, C>> {
using type = boost::mp11::mp_append<nodes_of_t<L>, nodes_of_t<R>>;
};

template <subgraph Lhs, subgraph Rhs> seq(Lhs, Rhs) -> seq<Lhs, Rhs>;
template <typename L, typename R, subgraph_identity I, typename C>
struct edges_of<seq<L, R, I, C>> {
using cross = boost::mp11::mp_product_q<make_edge_q<C>, finals_of_t<L>,
initials_of_t<R>>;
using type = boost::mp11::mp_append<edges_of_t<L>, edges_of_t<R>, cross>;
};
} // namespace detail

} // namespace flow::dsl

Expand Down
Loading