16 std::set<TTBase *> seen;
18 bool visited(
TTBase *p) {
return !seen.insert(p).second; }
33 std::cout <<
"ttg::Traverse: got a null op!\n";
37 if (visited(tt))
return true;
46 std::cout <<
"ttg::Traverse: got a null in!\n";
50 if (!in->is_connected()) {
51 std::cout <<
"ttg::Traverse: " << tt->
get_name() <<
" input terminal #" << count <<
" " << in->get_name()
52 <<
" is not connected\n";
61 for (
auto predecessor : in->get_predecessors()) {
63 std::cout <<
"ttg::Traverse: got a null predecessor!\n";
66 status &=
traverse(predecessor->get_tt());
75 std::cout <<
"ttg::Traverse: got a null out!\n";
79 if (!out->is_connected()) {
80 std::cout <<
"ttg::Traverse: " << tt->
get_name() <<
" output terminal #" << count <<
" "
81 << out->get_name() <<
" is not connected\n";
90 for (
auto successor : out->get_connections()) {
92 std::cout <<
"ttg::Traverse: got a null successor!\n";
95 status &=
traverse(successor->get_tt());
104 template <
typename TT>
105 std::enable_if_t<std::is_base_of_v<TTBase, TT> && !std::is_same_v<TT, TTBase>,
111 template <
typename TT>
112 std::enable_if_t<std::is_base_of_v<TTBase, TT>,
118 template <
typename TT,
typename Deleter>
119 std::enable_if_t<std::is_base_of_v<TTBase, TT>,
127 template <
typename Visitable>
142 template <
typename TTVisitor = detail::Traverse::null_visitor<TTBase>,
143 typename InVisitor = detail::Traverse::null_visitor<TerminalBase>,
144 typename OutVisitor = detail::Traverse::null_visitor<TerminalBase>>
148 std::is_void_v<meta::void_t<decltype(std::declval<TTVisitor>()(std::declval<TTBase *>()))>>,
149 "Traverse<TTVisitor,...>: TTVisitor(TTBase *op) must be a valid expression");
151 std::is_void_v<meta::void_t<decltype(std::declval<InVisitor>()(std::declval<TerminalBase *>()))>>,
152 "Traverse<,InVisitor,>: InVisitor(TerminalBase *op) must be a valid expression");
154 std::is_void_v<meta::void_t<decltype(std::declval<OutVisitor>()(std::declval<TerminalBase *>()))>>,
155 "Traverse<...,OutVisitor>: OutVisitor(TerminalBase *op) must be a valid expression");
157 template <
typename TTVisitor_ = detail::Traverse::null_visitor<TTBase>,
158 typename InVisitor_ = detail::Traverse::null_visitor<TerminalBase>,
159 typename OutVisitor_ = detail::Traverse::null_visitor<TerminalBase>>
160 Traverse(TTVisitor_ &&tt_v = TTVisitor_{}, InVisitor_ &&in_v = InVisitor_{}, OutVisitor_ &&out_v = OutVisitor_{})
161 : tt_visitor_(
std::forward<TTVisitor_>(tt_v))
162 , in_visitor_(
std::forward<InVisitor_>(in_v))
163 , out_visitor_(
std::forward<OutVisitor_>(out_v)){};
170 template <
typename TTBasePtr,
typename ... TTBasePtrs>
171 std::enable_if_t<std::is_base_of_v<TTBase, std::decay_t<decltype(*(std::declval<TTBasePtr>()))>> && (std::is_base_of_v<TTBase, std::decay_t<decltype(*(std::declval<TTBasePtrs>()))>> && ...),
174 TTBasePtr&& op, TTBasePtrs && ... ops) {
176 bool result = traverse_all(std::forward<TTBasePtr>(op), std::forward<TTBasePtrs>(ops)...);
182 TTVisitor tt_visitor_;
183 InVisitor in_visitor_;
184 OutVisitor out_visitor_;
186 template <
typename TTBasePtr,
typename ... TTBasePtrs>
187 bool traverse_all(TTBasePtr&& op, TTBasePtrs && ... ops) {
189 if constexpr(
sizeof...(ops) > 0) {
190 result &= traverse_all(std::forward<TTBasePtrs>(ops)...);
195 void ttfunc(TTBase *tt) { tt_visitor_(tt); }
197 void infunc(TerminalBase *in) { in_visitor_(in); }
199 void outfunc(TerminalBase *out) { out_visitor_(out); }
203 auto trivial_1param_lambda = [](
auto &&op) {};
205 template <
typename TTVisitor = decltype(trivial_1param_lambda)&,
typename InVisitor = decltype(trivial_1param_lambda)&,
typename OutVisitor = decltype(trivial_1param_lambda)&>
206 auto make_traverse(TTVisitor &&tt_v = trivial_1param_lambda, InVisitor &&in_v = trivial_1param_lambda, OutVisitor &&out_v = trivial_1param_lambda) {
208 std::remove_reference_t<OutVisitor>>{std::forward<TTVisitor>(tt_v), std::forward<InVisitor>(in_v),
209 std::forward<OutVisitor>(out_v)};
213 static Traverse<> verify{};
218 std::cout <<
"tt: " << (
void *)tt <<
" " << tt->get_name() <<
" numin " << tt->get_inputs().size() <<
" numout "
219 << tt->get_outputs().size() << std::endl;
222 std::cout <<
" in: " << in->get_index() <<
" " << in->get_name() <<
" " << in->get_key_type_str() <<
" "
223 << in->get_value_type_str() << std::endl;
226 std::cout <<
" out: " << out->get_index() <<
" " << out->get_name() <<
" " << out->get_key_type_str() <<
" "
227 << out->get_value_type_str() << std::endl;
A base class for all template tasks.
const std::vector< TerminalBase * > & get_outputs() const
Returns the vector of output terminals.
const std::vector< TerminalBase * > & get_inputs() const
Returns the vector of input terminals.
const std::string & get_name() const
Gets the name of this operation.
Traverses a graph of ops in depth-first manner following out edges.
const OutVisitor & out_visitor() const
const TTVisitor & tt_visitor() const
std::enable_if_t< std::is_base_of_v< TTBase, std::decay_t< decltype(*(std::declval< TTBasePtr >()))> > &&std::is_base_of_v< TTBase, std::decay_t< decltype(*(std::declval< TTBasePtrs >()))> bool operator()(TTBasePtr &&op, TTBasePtrs &&... ops)
const InVisitor & in_visitor() const
Traverse(TTVisitor_ &&tt_v=TTVisitor_{}, InVisitor_ &&in_v=InVisitor_{}, OutVisitor_ &&out_v=OutVisitor_{})
Traverses a graph of TTs in depth-first manner following out edges.
std::enable_if_t< std::is_base_of_v< TTBase, TT >, bool > traverse(const std::shared_ptr< TTBase > &tt)
virtual void ttfunc(TTBase *tt)=0
virtual void infunc(TerminalBase *in)=0
std::enable_if_t< std::is_base_of_v< TTBase, TT >, bool > traverse(const std::unique_ptr< TT, Deleter > &tt)
bool traverse(TTBase *tt)
virtual void outfunc(TerminalBase *out)=0
std::enable_if_t< std::is_base_of_v< TTBase, TT > &&!std::is_same_v< TT, TTBase >, bool > traverse(TT *tt)
top-level TTG namespace contains runtime-neutral functionality
auto make_traverse(TTVisitor &&tt_v=trivial_1param_lambda, InVisitor &&in_v=trivial_1param_lambda, OutVisitor &&out_v=trivial_1param_lambda)
void operator()(Visitable *)
visits a non-const Visitable object
void operator()(const Visitable *)
visits a const Visitable object