25 template <
typename keyT,
typename valueT>
41 bool is_pull_edge =
false;
42 std::vector<TerminalBase *> outs;
43 std::vector<Out<keyT, valueT> *> ins;
47 EdgeImpl() : name(
""), outs(), ins() {}
49 EdgeImpl(
const std::string &name) : name(name), outs(), ins() {}
52 : name(name), is_pull_edge(is_pull), container(c), outs(), ins() {
58 trace(
"Edge: ", name,
" : has multiple inputs");
62 try_to_connect_new_in(in);
67 trace(
"Edge: ", name,
" : has multiple outputs");
72 try_to_connect_new_out(out);
77 if (in && out) in->
connect(out);
86 if (in && out) in->
connect(out);
91 if (
diagnose() && ((ins.size() == 0 && outs.size() != 0) || (ins.size() != 0 && outs.size() == 0)) &&
94 "') with either in or out not assigned --- graph may be incomplete");
101 mutable std::vector<std::shared_ptr<EdgeImpl>> p;
107 static_assert(std::is_same_v<keyT, std::decay_t<keyT>>,
"Edge<keyT,valueT> assumes keyT is a non-decayable type");
108 static_assert(std::is_same_v<valueT, std::decay_t<valueT>>,
109 "Edge<keyT,valueT> assumes valueT is a non-decayable type");
111 Edge(
const std::string name =
"anonymous edge") : p(1) { p[0] = std::make_shared<EdgeImpl>(name); }
114 p[0] = std::make_shared<EdgeImpl>(name, is_pull, c);
118 template <
typename... valuesT,
typename = std::enable_if_t<(std::is_same_v<valuesT, valueT> && ...)>>
120 std::vector<Edge<keyT, valueT>> v = {
edges...};
122 if (!std::all_of(v.begin(), v.end(), [](
Edge<keyT, valueT> e) { return !e.is_pull_edge(); }))
123 throw std::runtime_error(
"Edge: fusing push and pull terminals is not supported.");
125 for (
auto &
edge : v) {
126 p.insert(p.end(),
edge.p.begin(),
edge.p.end());
137 for (
const auto &
edge : p) {
138 if (!
edge->ins.empty())
return true;
147 for (
auto &
edge : p)
edge->set_in(in);
152 for (
auto &
edge : p)
edge->set_out(out);
157 template <
typename Key = keyT,
typename Value = valueT>
158 std::enable_if_t<ttg::meta::is_all_void_v<Key, Value>>
fire()
const {
160 for (
auto &&out : e->outs) {
161 out->get_tt()->invoke();
167 template <
typename termsT>
169 template <
typename... termsT>
171 typedef std::tuple<
typename termsT::edge_type...>
type;
175 template <
typename edgesT>
177 template <
typename... edgesT>
179 typedef std::tuple<
typename edgesT::output_terminal_type...>
type;
182 template<
typename edgesT>
185 template<
typename... edgesT>
187 typedef std::tuple<
typename edgesT::value_type...>
type;
191 template <
typename keyT,
typename valuesT>
194 template <
typename keyT,
typename... valuesT>
196 using type = std::tuple<ttg::Edge<keyT, valuesT>...>;
199 template <
typename keyT,
typename valuesT>
Edge is used to connect In and Out terminals.
Edge< keyT, valueT > edge() const
void set_in(Out< keyT, valueT > *in) const
Sets the output terminal that goes into this Edge.
std::enable_if_t< ttg::meta::is_all_void_v< Key, Value > > fire() const
Edge(const std::string name="anonymous edge")
bool live() const
probes if this is already has at least one input received on the input terminal
Edge(const std::string name, bool is_pull, ttg::detail::ContainerWrapper< keyT, valueT > c)
Edge(const Edge< keyT, valuesT > &...edges)
Edge carrying a tuple of values.
bool is_pull_edge() const
Out< keyT, valueT > output_terminal_type
void set_out(TerminalBase *out) const
Sets the input terminal that this Edge goes into.
void connect(TerminalBase *in) override
Type get_type() const
Returns the terminal type.
void connect_pull_nopred(TerminalBase *p)
@ Write
can only be written to
typename edges_tuple< keyT, valuesT >::type edges_tuple_t
top-level TTG namespace contains runtime-neutral functionality
void print_error(const T &t, const Ts &... ts)
atomically prints to std::cerr a sequence of items (separated by ttg::print_separator) followed by st...
void trace(const T &t, const Ts &... ts)
auto edges(inedgesT &&...args)
Make a tuple of Edges to pass to.
std::tuple< ttg::Edge< keyT, valuesT >... > type
std::tuple< typename edgesT::output_terminal_type... > type
std::tuple< typename edgesT::value_type... > type
std::tuple< typename termsT::edge_type... > type