17 #ifndef __TBB_flow_graph_node_set_impl_H 18 #define __TBB_flow_graph_node_set_impl_H 20 #ifndef __TBB_flow_graph_H 21 #error Do not #include this internal file directly; use public TBB headers instead. 28 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 32 #define __TBB_MSVC_DISABLE_TRAILING_DECLTYPE (_MSC_VER >= 1900) 40 class get_graph_helper {
45 static graph& get(
const T&
object) {
46 return get_impl(
object, std::is_base_of<graph_node, T>());
53 return static_cast<const graph_node*>(&
object)->my_graph;
58 return object.graph_reference();
62 template<
typename Order,
typename... Nodes>
64 typedef Order order_type;
66 tbb::flow::tuple<Nodes&...> nodes;
67 node_set(Nodes&... ns) : nodes(ns...) {}
69 template <
typename... Nodes2>
70 node_set(
const node_set<order::undefined, Nodes2...>& set) : nodes(set.nodes) {}
72 graph& graph_reference()
const {
73 return get_graph_helper::get(std::get<0>(nodes));
77 namespace alias_helpers {
78 template <
typename T>
using output_type =
typename T::output_type;
79 template <
typename T>
using output_ports_type =
typename T::output_ports_type;
80 template <
typename T>
using input_type =
typename T::input_type;
81 template <
typename T>
using input_ports_type =
typename T::input_ports_type;
97 struct is_sender : std::is_base_of<sender<typename T::output_type>, T> {};
100 struct is_receiver : std::is_base_of<receiver<typename T::input_type>, T> {};
102 template <
typename Node>
105 template <
typename... Args>
106 struct is_async_node<
tbb::flow::interface11::async_node<Args...>> :
std::true_type {};
108 template<
typename FirstPredecessor,
typename... Predecessors>
109 node_set<order::following, FirstPredecessor, Predecessors...>
110 follows(FirstPredecessor& first_predecessor, Predecessors&... predecessors) {
112 has_output_type<Predecessors>...>::
value),
113 "Not all node's predecessors has output_type typedef");
115 "Not all node's predecessors are senders");
116 return node_set<order::following, FirstPredecessor, Predecessors...>(first_predecessor, predecessors...);
119 template<
typename... Predecessors>
120 node_set<order::following, Predecessors...>
121 follows(node_set<order::undefined, Predecessors...>& predecessors_set) {
123 "Not all nodes in the set has output_type typedef");
125 "Not all nodes in the set are senders");
126 return node_set<order::following, Predecessors...>(predecessors_set);
129 template<
typename FirstSuccessor,
typename... Successors>
130 node_set<order::preceding, FirstSuccessor, Successors...>
131 precedes(FirstSuccessor& first_successor, Successors&... successors) {
133 has_input_type<Successors>...>::
value),
134 "Not all node's successors has input_type typedef");
136 "Not all node's successors are receivers");
137 return node_set<order::preceding, FirstSuccessor, Successors...>(first_successor, successors...);
140 template<
typename... Successors>
141 node_set<order::preceding, Successors...>
142 precedes(node_set<order::undefined, Successors...>& successors_set) {
144 "Not all nodes in the set has input_type typedef");
146 "Not all nodes in the set are receivers");
147 return node_set<order::preceding, Successors...>(successors_set);
150 template <
typename Node,
typename... Nodes>
151 node_set<order::undefined, Node, Nodes...>
152 make_node_set(Node& first_node, Nodes&... nodes) {
153 return node_set<order::undefined, Node, Nodes...>(first_node, nodes...);
157 class successor_selector {
158 template <
typename NodeType>
159 static auto get_impl(NodeType& node,
std::true_type) -> decltype(input_port<I>(node)) {
160 return input_port<I>(node);
163 template <
typename NodeType>
164 static NodeType& get_impl(NodeType& node,
std::false_type) {
return node; }
167 template <
typename NodeType>
168 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE 169 static auto& get(NodeType& node)
171 static auto get(NodeType& node) -> decltype(get_impl(node, has_input_ports_type<NodeType>()))
174 return get_impl(node, has_input_ports_type<NodeType>());
179 class predecessor_selector {
180 template <
typename NodeType>
181 static auto internal_get(NodeType& node,
std::true_type) -> decltype(output_port<I>(node)) {
182 return output_port<I>(node);
185 template <
typename NodeType>
186 static NodeType& internal_get(NodeType& node,
std::false_type) {
return node;}
188 template <
typename NodeType>
189 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE 192 static auto get_impl(NodeType& node,
std::false_type) -> decltype(internal_get(node, has_output_ports_type<NodeType>()))
195 return internal_get(node, has_output_ports_type<NodeType>());
198 template <
typename AsyncNode>
199 static AsyncNode& get_impl(AsyncNode& node,
std::true_type) {
return node; }
202 template <
typename NodeType>
203 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE 204 static auto& get(NodeType& node)
206 static auto get(NodeType& node) -> decltype(get_impl(node, is_async_node<NodeType>()))
209 return get_impl(node, is_async_node<NodeType>());
214 class make_edges_helper {
216 template<
typename PredecessorsTuple,
typename NodeType>
217 static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) {
218 make_edge(std::get<I>(predecessors), successor_selector<I>::get(node));
219 make_edges_helper<I - 1>::connect_predecessors(predecessors, node);
222 template<
typename SuccessorsTuple,
typename NodeType>
223 static void connect_successors(NodeType& node, SuccessorsTuple& successors) {
224 make_edge(predecessor_selector<I>::get(node), std::get<I>(successors));
225 make_edges_helper<I - 1>::connect_successors(node, successors);
230 struct make_edges_helper<0> {
231 template<
typename PredecessorsTuple,
typename NodeType>
232 static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) {
233 make_edge(std::get<0>(predecessors), successor_selector<0>::get(node));
236 template<
typename SuccessorsTuple,
typename NodeType>
237 static void connect_successors(NodeType& node, SuccessorsTuple& successors) {
238 make_edge(predecessor_selector<0>::get(node), std::get<0>(successors));
243 template<
typename NodeType,
typename OrderFlagType,
typename... Args>
244 void make_edges(
const node_set<OrderFlagType, Args...>&
s, NodeType& node) {
245 const std::size_t SetSize = tbb::flow::tuple_size<decltype(
s.nodes)>
::value;
246 make_edges_helper<SetSize - 1>::connect_predecessors(
s.nodes, node);
249 template <
typename NodeType,
typename OrderFlagType,
typename... Args>
250 void make_edges(NodeType& node,
const node_set<OrderFlagType, Args...>&
s) {
251 const std::size_t SetSize = tbb::flow::tuple_size<decltype(
s.nodes)>
::value;
252 make_edges_helper<SetSize - 1>::connect_successors(node,
s.nodes);
255 template <
typename NodeType,
typename... Nodes>
256 void make_edges_in_order(
const node_set<order::following, Nodes...>& ns, NodeType& node) {
257 make_edges(ns, node);
260 template <
typename NodeType,
typename... Nodes>
261 void make_edges_in_order(
const node_set<order::preceding, Nodes...>& ns, NodeType& node) {
262 make_edges(node, ns);
265 #endif // __TBB_CPP11_PRESENT 269 #endif // __TBB_flow_graph_node_set_impl_H bool_constant< true > true_type
bool_constant< false > false_type
#define __TBB_STATIC_ASSERT(condition, msg)
void make_edge(sender< T > &p, receiver< T > &s)
Makes an edge between a single predecessor and a single successor.
void const char const char int ITT_FORMAT __itt_group_sync s
typename supports_impl< T, void, Checks... >::type supports
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value