Skip to content
Draft
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
51 changes: 51 additions & 0 deletions include/flow/dsl/flatten.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include <flow/dsl/subgraph_identity.hpp>
#include <flow/dsl/walk.hpp>

#include <stdx/tuple.hpp>

#include <boost/mp11.hpp>

#include <type_traits>

namespace flow::dsl::detail {

template <typename E> struct initials_of {
using type = boost::mp11::mp_list<E>;
};

template <typename E> struct finals_of {
using type = boost::mp11::mp_list<E>;
};

template <typename E> struct all_mentioned_of {
using type = boost::mp11::mp_list<E>;
};

template <typename E> struct nodes_of {
using type =
std::conditional_t<E::identity == subgraph_identity::VALUE,
boost::mp11::mp_list<E>, boost::mp11::mp_list<>>;
};

template <typename E> struct edges_of {
using type = boost::mp11::mp_list<>;
};

template <typename N>
using star_t = std::remove_cvref_t<decltype(*std::declval<N>())>;

template <typename Cond> struct make_edge_q {
template <typename Pair>
using fn = edge<boost::mp11::mp_first<Pair>, boost::mp11::mp_second<Pair>,
Cond>;
};

template <typename List> struct to_tuple;
template <typename... Ts> struct to_tuple<boost::mp11::mp_list<Ts...>> {
constexpr static auto value = stdx::tuple<Ts...>{};
};
template <typename List> constexpr auto to_tuple_v = to_tuple<List>::value;
Comment on lines +45 to +49

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use boost::mp11::mp_apply<stdx::tuple, List>


} // namespace flow::dsl::detail
71 changes: 51 additions & 20 deletions include/flow/dsl/par.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#pragma once

#include <flow/dsl/flatten.hpp>
#include <flow/dsl/subgraph_identity.hpp>
#include <flow/dsl/walk.hpp>

#include <stdx/tuple_algorithms.hpp>

#include <boost/mp11.hpp>

namespace flow::dsl {
template <subgraph Lhs, subgraph Rhs,
subgraph_identity Identity = subgraph_identity::REFERENCE>
Expand All @@ -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<typename detail::initials_of<par>::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<typename detail::finals_of<par>::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<typename detail::nodes_of<par>::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<typename detail::all_mentioned_of<par>::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<typename detail::edges_of<par>::type>;
}
};

template <subgraph Lhs, subgraph Rhs> par(Lhs, Rhs) -> par<Lhs, Rhs>;

namespace detail {
template <typename L, typename R, subgraph_identity I>
struct initials_of<par<L, R, I>> {
using type = boost::mp11::mp_append<typename initials_of<L>::type,
typename initials_of<R>::type>;
};

template <typename L, typename R, subgraph_identity I>
struct finals_of<par<L, R, I>> {
using type = boost::mp11::mp_append<typename finals_of<L>::type,
typename finals_of<R>::type>;
};

template <typename L, typename R, subgraph_identity I>
struct all_mentioned_of<par<L, R, I>> {
using type = boost::mp11::mp_append<typename all_mentioned_of<L>::type,
typename all_mentioned_of<R>::type>;
};

template <typename L, typename R, subgraph_identity I>
struct nodes_of<par<L, R, I>> {
using value_nodes = boost::mp11::mp_transform<
star_t,
boost::mp11::mp_unique<typename all_mentioned_of<par<L, R, I>>::type>>;
using ref_nodes = boost::mp11::mp_append<typename nodes_of<L>::type,
typename nodes_of<R>::type>;
using type = std::conditional_t<I == subgraph_identity::VALUE, value_nodes,
ref_nodes>;
};

template <typename L, typename R, subgraph_identity I>
struct edges_of<par<L, R, I>> {
using type = boost::mp11::mp_append<typename edges_of<L>::type,
typename edges_of<R>::type>;
};
} // namespace detail

} // namespace flow::dsl

template <flow::dsl::subgraph Lhs, flow::dsl::subgraph Rhs>
Expand Down
83 changes: 53 additions & 30 deletions include/flow/dsl/seq.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#pragma once

#include <flow/dsl/flatten.hpp>
#include <flow/dsl/subgraph_identity.hpp>
#include <flow/dsl/walk.hpp>
#include <nexus/detail/runtime_conditional.hpp>

#include <stdx/tuple_algorithms.hpp>

#include <boost/mp11.hpp>

namespace flow::dsl {
template <subgraph Lhs, subgraph Rhs,
subgraph_identity Identity = subgraph_identity::REFERENCE,
Expand All @@ -21,49 +24,69 @@ struct seq {
}

private:
friend constexpr auto tag_invoke(get_initials_t, seq const &s) {
return get_initials(s.lhs);
friend constexpr auto tag_invoke(get_initials_t, seq const &) {
return detail::to_tuple_v<typename detail::initials_of<seq>::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<typename detail::finals_of<seq>::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<typename detail::nodes_of<seq>::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<typename detail::all_mentioned_of<seq>::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(
[]<typename P>(P const &) {
return edge<stdx::tuple_element_t<0, P>,
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<typename detail::edges_of<seq>::type>;
}
};

template <subgraph Lhs, subgraph Rhs> seq(Lhs, Rhs) -> seq<Lhs, 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;
};

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;
};

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<typename all_mentioned_of<L>::type,
typename all_mentioned_of<R>::type>;
};

template <typename L, typename R, subgraph_identity I, typename C>
struct nodes_of<seq<L, R, I, C>> {
using value_nodes = boost::mp11::mp_transform<
star_t, boost::mp11::mp_unique<
typename all_mentioned_of<seq<L, R, I, C>>::type>>;
using ref_nodes = boost::mp11::mp_append<typename nodes_of<L>::type,
typename nodes_of<R>::type>;
using type = std::conditional_t<I == subgraph_identity::VALUE, value_nodes,
ref_nodes>;
};

template <typename L, typename R, subgraph_identity I, typename C>
struct edges_of<seq<L, R, I, C>> {
using pairs =
boost::mp11::mp_product<boost::mp11::mp_list,
typename finals_of<L>::type,
typename initials_of<R>::type>;
using cross = boost::mp11::mp_transform_q<make_edge_q<C>, pairs>;
using type = boost::mp11::mp_append<typename edges_of<L>::type,
typename edges_of<R>::type, cross>;
};
} // namespace detail

} // namespace flow::dsl

template <flow::dsl::subgraph Lhs, flow::dsl::subgraph Rhs>
Expand Down
Loading