17 #ifndef __TBB_flow_graph_nodes_deduction_H
18 #define __TBB_flow_graph_nodes_deduction_H
20 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
24 namespace interface11 {
26 template <
typename Input,
typename Output>
27 struct declare_body_types {
28 using input_type = Input;
29 using output_type = Output;
32 template <
typename T>
struct body_types;
34 template <
typename T,
typename Input,
typename Output>
35 struct body_types<Output (T::*)(const Input&) const> : declare_body_types<Input, Output> {};
37 template <
typename T,
typename Input,
typename Output>
38 struct body_types<Output (T::*)(const Input&)> : declare_body_types<Input, Output> {};
40 template <
typename T,
typename Input,
typename Output>
41 struct body_types<Output (T::*)(Input&) const> : declare_body_types<Input, Output> {};
43 template <
typename T,
typename Input,
typename Output>
44 struct body_types<Output (T::*)(Input&)> : declare_body_types<Input, Output> {};
46 template <
typename Input,
typename Output>
47 struct body_types<Output (*)(Input&)> : declare_body_types<Input, Output> {};
49 template <
typename Input,
typename Output>
50 struct body_types<Output (*)(
const Input&)> : declare_body_types<Input, Output> {};
52 template <
typename Body>
53 using input_t =
typename body_types<Body>::input_type;
55 template <
typename Body>
56 using output_t =
typename body_types<Body>::output_type;
58 template <
typename T,
typename Input,
typename Output>
59 auto decide_on_operator_overload(Output (T::*
name)(
const Input&)
const)->decltype(
name);
61 template <
typename T,
typename Input,
typename Output>
62 auto decide_on_operator_overload(Output (T::*
name)(
const Input&))->decltype(
name);
64 template <
typename T,
typename Input,
typename Output>
65 auto decide_on_operator_overload(Output (T::*
name)(Input&)
const)->decltype(
name);
67 template <
typename T,
typename Input,
typename Output>
68 auto decide_on_operator_overload(Output (T::*
name)(Input&))->decltype(
name);
70 template <
typename Input,
typename Output>
71 auto decide_on_operator_overload(Output (*
name)(
const Input&))->decltype(
name);
73 template <
typename Input,
typename Output>
74 auto decide_on_operator_overload(Output (*
name)(Input&))->decltype(
name);
76 template <
typename Body>
77 decltype(decide_on_operator_overload(&Body::operator())) decide_on_callable_type(
int);
79 template <typename Body>
80 decltype(decide_on_operator_overload(std::declval<Body>())) decide_on_callable_type(...);
83 #if TBB_USE_SOURCE_NODE_AS_ALIAS
84 template <
typename GraphOrSet,
typename Body>
85 source_node(GraphOrSet&&, Body)
86 ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
88 template <
typename GraphOrSet,
typename Body>
89 source_node(GraphOrSet&&, Body,
bool =
true)
90 ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
93 template <
typename GraphOrSet,
typename Body>
94 input_node(GraphOrSet&&, Body,
bool =
true)
95 ->input_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
97 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
99 template <
typename NodeSet>
100 struct decide_on_set;
102 template <
typename Node,
typename... Nodes>
103 struct decide_on_set<node_set<
internal::order::following, Node, Nodes...>> {
104 using type =
typename Node::output_type;
107 template <
typename Node,
typename... Nodes>
108 struct decide_on_set<node_set<
internal::order::preceding, Node, Nodes...>> {
109 using type =
typename Node::input_type;
112 template <
typename NodeSet>
113 using decide_on_set_t =
typename decide_on_set<std::decay_t<NodeSet>>
::type;
115 template <
typename NodeSet>
116 broadcast_node(
const NodeSet&)
117 ->broadcast_node<decide_on_set_t<NodeSet>>;
119 template <
typename NodeSet>
120 buffer_node(
const NodeSet&)
121 ->buffer_node<decide_on_set_t<NodeSet>>;
123 template <
typename NodeSet>
124 queue_node(
const NodeSet&)
125 ->queue_node<decide_on_set_t<NodeSet>>;
126 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
128 template <
typename GraphOrProxy,
typename Sequencer>
129 sequencer_node(GraphOrProxy&&, Sequencer)
130 ->sequencer_node<input_t<decltype(decide_on_callable_type<Sequencer>(0))>>;
132 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
133 template <
typename NodeSet,
typename Compare>
134 priority_queue_node(
const NodeSet&,
const Compare&)
135 ->priority_queue_node<decide_on_set_t<NodeSet>, Compare>;
137 template <
typename NodeSet>
138 priority_queue_node(
const NodeSet&)
139 ->priority_queue_node<decide_on_set_t<NodeSet>, std::less<decide_on_set_t<NodeSet>>>;
140 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
142 template <
typename Key>
147 template <
typename T>
148 struct join_key<const T&> {
152 template <
typename Key>
155 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
156 template <
typename Policy,
typename... Predecessors>
157 join_node(
const node_set<internal::order::following, Predecessors...>&, Policy)
158 ->join_node<std::tuple<
typename Predecessors::output_type...>,
161 template <
typename Policy,
typename Successor,
typename... Successors>
162 join_node(
const node_set<internal::order::preceding, Successor, Successors...>&, Policy)
163 ->join_node<
typename Successor::input_type, Policy>;
165 template <
typename... Predecessors>
166 join_node(
const node_set<internal::order::following, Predecessors...>)
167 ->join_node<std::tuple<
typename Predecessors::output_type...>,
170 template <
typename Successor,
typename... Successors>
171 join_node(
const node_set<internal::order::preceding, Successor, Successors...>)
172 ->join_node<
typename Successor::input_type, queueing>;
175 template <
typename GraphOrProxy,
typename Body,
typename... Bodies>
176 join_node(GraphOrProxy&&, Body, Bodies...)
177 ->join_node<std::tuple<input_t<decltype(decide_on_callable_type<Body>(0))>,
178 input_t<decltype(decide_on_callable_type<Bodies>(0))>...>,
179 key_matching<join_key_t<output_t<decltype(decide_on_callable_type<Body>(0))>>>>;
181 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
182 template <
typename... Predecessors>
183 indexer_node(
const node_set<internal::order::following, Predecessors...>&)
184 ->indexer_node<
typename Predecessors::output_type...>;
187 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
188 template <
typename NodeSet>
189 limiter_node(
const NodeSet&,
size_t)
190 ->limiter_node<decide_on_set_t<NodeSet>>;
192 template <
typename Predecessor,
typename... Predecessors>
193 split_node(
const node_set<internal::order::following, Predecessor, Predecessors...>&)
194 ->split_node<
typename Predecessor::output_type>;
196 template <
typename... Successors>
197 split_node(
const node_set<internal::order::preceding, Successors...>&)
198 ->split_node<std::tuple<
typename Successors::input_type...>>;
202 template <
typename GraphOrSet,
typename Body,
typename Policy>
203 function_node(GraphOrSet&&,
206 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
207 output_t<decltype(decide_on_callable_type<Body>(0))>,
210 template <
typename GraphOrSet,
typename Body>
211 function_node(GraphOrSet&&,
size_t,
213 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
214 output_t<decltype(decide_on_callable_type<Body>(0))>,
217 template <
typename Output>
218 struct continue_output {
223 struct continue_output<
void> {
224 using type = continue_msg;
227 template <
typename T>
230 template <
typename GraphOrSet,
typename Body,
typename Policy>
231 continue_node(GraphOrSet&&, Body,
233 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
236 template <
typename GraphOrSet,
typename Body,
typename Policy>
237 continue_node(GraphOrSet&&,
240 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
243 template <
typename GraphOrSet,
typename Body>
244 continue_node(GraphOrSet&&,
246 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
249 template <
typename GraphOrSet,
typename Body>
250 continue_node(GraphOrSet&&,
int,
252 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
255 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
257 template <
typename NodeSet>
258 overwrite_node(
const NodeSet&)
259 ->overwrite_node<decide_on_set_t<NodeSet>>;
261 template <
typename NodeSet>
262 write_once_node(
const NodeSet&)
263 ->write_once_node<decide_on_set_t<NodeSet>>;
264 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
269 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
270 #endif // __TBB_flow_graph_nodes_deduction_H