17#ifndef __TBB_flow_graph_nodes_deduction_H
18#define __TBB_flow_graph_nodes_deduction_H
20#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
24namespace interface11 {
26template <
typename Input,
typename Output>
27struct declare_body_types {
28 using input_type = Input;
29 using output_type = Output;
34template <
typename Output>
35struct declare_body_types<NoInputBody, Output> {
36 using output_type = Output;
39template <
typename T>
struct body_types;
41template <
typename T,
typename Input,
typename Output>
42struct body_types<Output (T::*)(const Input&) const> : declare_body_types<Input, Output> {};
44template <
typename T,
typename Input,
typename Output>
45struct body_types<Output (T::*)(const Input&)> : declare_body_types<Input, Output> {};
47template <
typename T,
typename Input,
typename Output>
48struct body_types<Output (T::*)(Input&) const> : declare_body_types<Input, Output> {};
50template <
typename T,
typename Input,
typename Output>
51struct body_types<Output (T::*)(Input&)> : declare_body_types<Input, Output> {};
53template <
typename Input,
typename Output>
54struct body_types<Output (*)(Input&)> : declare_body_types<Input, Output> {};
56template <
typename Input,
typename Output>
57struct body_types<Output (*)(
const Input&)> : declare_body_types<Input, Output> {};
59template <
typename T,
typename Output>
60struct body_types<Output (T::*)(flow_control&) const> : declare_body_types<NoInputBody, Output> {};
62template <
typename T,
typename Output>
63struct body_types<Output (T::*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
65template <
typename Output>
66struct body_types<Output (*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
68template <
typename Body>
69using input_t =
typename body_types<Body>::input_type;
71template <
typename Body>
72using output_t =
typename body_types<Body>::output_type;
74template <
typename T,
typename Input,
typename Output>
75auto decide_on_operator_overload(Output (T::*
name)(
const Input&)
const)->decltype(
name);
77template <
typename T,
typename Input,
typename Output>
78auto decide_on_operator_overload(Output (T::*
name)(
const Input&))->decltype(
name);
80template <
typename T,
typename Input,
typename Output>
81auto decide_on_operator_overload(Output (T::*
name)(Input&)
const)->decltype(
name);
83template <
typename T,
typename Input,
typename Output>
84auto decide_on_operator_overload(Output (T::*
name)(Input&))->decltype(
name);
86template <
typename Input,
typename Output>
87auto decide_on_operator_overload(Output (*
name)(
const Input&))->decltype(
name);
89template <
typename Input,
typename Output>
90auto decide_on_operator_overload(Output (*
name)(Input&))->decltype(
name);
92template <
typename Body>
93decltype(decide_on_operator_overload(&Body::operator())) decide_on_callable_type(
int);
95template <
typename Body>
96decltype(decide_on_operator_overload(std::declval<Body>())) decide_on_callable_type(...);
99#if TBB_USE_SOURCE_NODE_AS_ALIAS
100#if TBB_DEPRECATED_INPUT_NODE_BODY
101template <
typename GraphOrSet,
typename Body>
102source_node(GraphOrSet&&, Body)
103->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
105template <
typename GraphOrSet,
typename Body>
106source_node(GraphOrSet&&, Body)
107->source_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
110template <
typename GraphOrSet,
typename Body>
111source_node(GraphOrSet&&, Body,
bool =
true)
112->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
115#if TBB_DEPRECATED_INPUT_NODE_BODY
116template <
typename GraphOrSet,
typename Body>
117input_node(GraphOrSet&&, Body,
bool =
true)
118->input_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
120template <
typename GraphOrSet,
typename Body>
121input_node(GraphOrSet&&, Body)
122->input_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
125#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
127template <
typename NodeSet>
130template <
typename Node,
typename... Nodes>
131struct decide_on_set<node_set<
internal::order::following, Node, Nodes...>> {
132 using type =
typename Node::output_type;
135template <
typename Node,
typename... Nodes>
136struct decide_on_set<node_set<
internal::order::preceding, Node, Nodes...>> {
137 using type =
typename Node::input_type;
140template <
typename NodeSet>
141using decide_on_set_t =
typename decide_on_set<std::decay_t<NodeSet>>
::type;
143template <
typename NodeSet>
144broadcast_node(
const NodeSet&)
145->broadcast_node<decide_on_set_t<NodeSet>>;
147template <
typename NodeSet>
148buffer_node(
const NodeSet&)
149->buffer_node<decide_on_set_t<NodeSet>>;
151template <
typename NodeSet>
152queue_node(
const NodeSet&)
153->queue_node<decide_on_set_t<NodeSet>>;
156template <
typename GraphOrProxy,
typename Sequencer>
157sequencer_node(GraphOrProxy&&, Sequencer)
158->sequencer_node<input_t<decltype(decide_on_callable_type<Sequencer>(0))>>;
160#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
161template <
typename NodeSet,
typename Compare>
162priority_queue_node(
const NodeSet&,
const Compare&)
163->priority_queue_node<decide_on_set_t<NodeSet>, Compare>;
165template <
typename NodeSet>
166priority_queue_node(
const NodeSet&)
167->priority_queue_node<decide_on_set_t<NodeSet>, std::less<decide_on_set_t<NodeSet>>>;
170template <
typename Key>
176struct join_key<const T&> {
180template <
typename Key>
181using join_key_t =
typename join_key<Key>::type;
183#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
184template <
typename Policy,
typename... Predecessors>
185join_node(
const node_set<internal::order::following, Predecessors...>&, Policy)
186->join_node<std::tuple<
typename Predecessors::output_type...>,
189template <
typename Policy,
typename Successor,
typename... Successors>
190join_node(
const node_set<internal::order::preceding, Successor, Successors...>&, Policy)
191->join_node<
typename Successor::input_type, Policy>;
193template <
typename... Predecessors>
194join_node(
const node_set<internal::order::following, Predecessors...>)
195->join_node<std::tuple<
typename Predecessors::output_type...>,
198template <
typename Successor,
typename... Successors>
199join_node(
const node_set<internal::order::preceding, Successor, Successors...>)
200->join_node<
typename Successor::input_type, queueing>;
203template <
typename GraphOrProxy,
typename Body,
typename... Bodies>
204join_node(GraphOrProxy&&, Body, Bodies...)
205->join_node<std::tuple<input_t<decltype(decide_on_callable_type<Body>(0))>,
206 input_t<
decltype(decide_on_callable_type<Bodies>(0))>...>,
207 key_matching<join_key_t<output_t<
decltype(decide_on_callable_type<Body>(0))>>>>;
209#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
210template <
typename... Predecessors>
211indexer_node(
const node_set<internal::order::following, Predecessors...>&)
212->indexer_node<
typename Predecessors::output_type...>;
215#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
216template <
typename NodeSet>
217limiter_node(
const NodeSet&,
size_t)
218->limiter_node<decide_on_set_t<NodeSet>>;
220template <
typename Predecessor,
typename... Predecessors>
221split_node(
const node_set<internal::order::following, Predecessor, Predecessors...>&)
222->split_node<
typename Predecessor::output_type>;
224template <
typename... Successors>
225split_node(
const node_set<internal::order::preceding, Successors...>&)
226->split_node<std::tuple<
typename Successors::input_type...>>;
230template <
typename GraphOrSet,
typename Body,
typename Policy>
231function_node(GraphOrSet&&,
234->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
235 output_t<
decltype(decide_on_callable_type<Body>(0))>,
238template <
typename GraphOrSet,
typename Body>
239function_node(GraphOrSet&&,
size_t,
241->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
242 output_t<
decltype(decide_on_callable_type<Body>(0))>,
245template <
typename Output>
246struct continue_output {
251struct continue_output<
void> {
252 using type = continue_msg;
256using continue_output_t =
typename continue_output<T>::type;
258template <
typename GraphOrSet,
typename Body,
typename Policy>
259continue_node(GraphOrSet&&, Body,
261->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
264template <
typename GraphOrSet,
typename Body,
typename Policy>
265continue_node(GraphOrSet&&,
268->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
271template <
typename GraphOrSet,
typename Body>
272continue_node(GraphOrSet&&,
274->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
277template <
typename GraphOrSet,
typename Body>
278continue_node(GraphOrSet&&,
int,
280->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
283#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
285template <
typename NodeSet>
286overwrite_node(
const NodeSet&)
287->overwrite_node<decide_on_set_t<NodeSet>>;
289template <
typename NodeSet>
290write_once_node(
const NodeSet&)
291->write_once_node<decide_on_set_t<NodeSet>>;
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name
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 ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
static const node_priority_t no_priority