File indexing completed on 2025-07-30 08:46:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_flow_graph_nodes_deduction_H
0018 #define __TBB_flow_graph_nodes_deduction_H
0019
0020 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
0021
0022 namespace tbb {
0023 namespace detail {
0024 namespace d1 {
0025
0026 template <typename Input, typename Output>
0027 struct declare_body_types {
0028 using input_type = Input;
0029 using output_type = Output;
0030 };
0031
0032 struct NoInputBody {};
0033
0034 template <typename Output>
0035 struct declare_body_types<NoInputBody, Output> {
0036 using output_type = Output;
0037 };
0038
0039 template <typename T> struct body_types;
0040
0041 template <typename T, typename Input, typename Output>
0042 struct body_types<Output (T::*)(const Input&) const> : declare_body_types<Input, Output> {};
0043
0044 template <typename T, typename Input, typename Output>
0045 struct body_types<Output (T::*)(const Input&)> : declare_body_types<Input, Output> {};
0046
0047 template <typename T, typename Input, typename Output>
0048 struct body_types<Output (T::*)(Input&) const> : declare_body_types<Input, Output> {};
0049
0050 template <typename T, typename Input, typename Output>
0051 struct body_types<Output (T::*)(Input&)> : declare_body_types<Input, Output> {};
0052
0053 template <typename T, typename Output>
0054 struct body_types<Output (T::*)(flow_control&) const> : declare_body_types<NoInputBody, Output> {};
0055
0056 template <typename T, typename Output>
0057 struct body_types<Output (T::*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
0058
0059 template <typename Input, typename Output>
0060 struct body_types<Output (*)(Input&)> : declare_body_types<Input, Output> {};
0061
0062 template <typename Input, typename Output>
0063 struct body_types<Output (*)(const Input&)> : declare_body_types<Input, Output> {};
0064
0065 template <typename Output>
0066 struct body_types<Output (*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
0067
0068 template <typename Body>
0069 using input_t = typename body_types<Body>::input_type;
0070
0071 template <typename Body>
0072 using output_t = typename body_types<Body>::output_type;
0073
0074 template <typename T, typename Input, typename Output>
0075 auto decide_on_operator_overload(Output (T::*name)(const Input&) const)->decltype(name);
0076
0077 template <typename T, typename Input, typename Output>
0078 auto decide_on_operator_overload(Output (T::*name)(const Input&))->decltype(name);
0079
0080 template <typename T, typename Input, typename Output>
0081 auto decide_on_operator_overload(Output (T::*name)(Input&) const)->decltype(name);
0082
0083 template <typename T, typename Input, typename Output>
0084 auto decide_on_operator_overload(Output (T::*name)(Input&))->decltype(name);
0085
0086 template <typename Input, typename Output>
0087 auto decide_on_operator_overload(Output (*name)(const Input&))->decltype(name);
0088
0089 template <typename Input, typename Output>
0090 auto decide_on_operator_overload(Output (*name)(Input&))->decltype(name);
0091
0092 template <typename Body>
0093 decltype(decide_on_operator_overload(&Body::operator())) decide_on_callable_type(int);
0094
0095 template <typename Body>
0096 decltype(decide_on_operator_overload(std::declval<Body>())) decide_on_callable_type(...);
0097
0098
0099
0100 template <typename GraphOrSet, typename Body>
0101 input_node(GraphOrSet&&, Body)
0102 ->input_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
0103
0104 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0105
0106 template <typename NodeSet>
0107 struct decide_on_set;
0108
0109 template <typename Node, typename... Nodes>
0110 struct decide_on_set<node_set<order::following, Node, Nodes...>> {
0111 using type = typename Node::output_type;
0112 };
0113
0114 template <typename Node, typename... Nodes>
0115 struct decide_on_set<node_set<order::preceding, Node, Nodes...>> {
0116 using type = typename Node::input_type;
0117 };
0118
0119 template <typename NodeSet>
0120 using decide_on_set_t = typename decide_on_set<std::decay_t<NodeSet>>::type;
0121
0122 template <typename NodeSet>
0123 broadcast_node(const NodeSet&)
0124 ->broadcast_node<decide_on_set_t<NodeSet>>;
0125
0126 template <typename NodeSet>
0127 buffer_node(const NodeSet&)
0128 ->buffer_node<decide_on_set_t<NodeSet>>;
0129
0130 template <typename NodeSet>
0131 queue_node(const NodeSet&)
0132 ->queue_node<decide_on_set_t<NodeSet>>;
0133 #endif
0134
0135 template <typename GraphOrProxy, typename Sequencer>
0136 sequencer_node(GraphOrProxy&&, Sequencer)
0137 ->sequencer_node<input_t<decltype(decide_on_callable_type<Sequencer>(0))>>;
0138
0139 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0140 template <typename NodeSet, typename Compare>
0141 priority_queue_node(const NodeSet&, const Compare&)
0142 ->priority_queue_node<decide_on_set_t<NodeSet>, Compare>;
0143
0144 template <typename NodeSet>
0145 priority_queue_node(const NodeSet&)
0146 ->priority_queue_node<decide_on_set_t<NodeSet>, std::less<decide_on_set_t<NodeSet>>>;
0147 #endif
0148
0149 template <typename Key>
0150 struct join_key {
0151 using type = Key;
0152 };
0153
0154 template <typename T>
0155 struct join_key<const T&> {
0156 using type = T&;
0157 };
0158
0159 template <typename Key>
0160 using join_key_t = typename join_key<Key>::type;
0161
0162 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0163 template <typename Policy, typename... Predecessors>
0164 join_node(const node_set<order::following, Predecessors...>&, Policy)
0165 ->join_node<std::tuple<typename Predecessors::output_type...>,
0166 Policy>;
0167
0168 template <typename Policy, typename Successor, typename... Successors>
0169 join_node(const node_set<order::preceding, Successor, Successors...>&, Policy)
0170 ->join_node<typename Successor::input_type, Policy>;
0171
0172 template <typename... Predecessors>
0173 join_node(const node_set<order::following, Predecessors...>)
0174 ->join_node<std::tuple<typename Predecessors::output_type...>,
0175 queueing>;
0176
0177 template <typename Successor, typename... Successors>
0178 join_node(const node_set<order::preceding, Successor, Successors...>)
0179 ->join_node<typename Successor::input_type, queueing>;
0180 #endif
0181
0182 template <typename GraphOrProxy, typename Body, typename... Bodies>
0183 join_node(GraphOrProxy&&, Body, Bodies...)
0184 ->join_node<std::tuple<input_t<decltype(decide_on_callable_type<Body>(0))>,
0185 input_t<decltype(decide_on_callable_type<Bodies>(0))>...>,
0186 key_matching<join_key_t<output_t<decltype(decide_on_callable_type<Body>(0))>>>>;
0187
0188 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0189 template <typename... Predecessors>
0190 indexer_node(const node_set<order::following, Predecessors...>&)
0191 ->indexer_node<typename Predecessors::output_type...>;
0192 #endif
0193
0194 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0195 template <typename NodeSet>
0196 limiter_node(const NodeSet&, size_t)
0197 ->limiter_node<decide_on_set_t<NodeSet>>;
0198
0199 template <typename Predecessor, typename... Predecessors>
0200 split_node(const node_set<order::following, Predecessor, Predecessors...>&)
0201 ->split_node<typename Predecessor::output_type>;
0202
0203 template <typename... Successors>
0204 split_node(const node_set<order::preceding, Successors...>&)
0205 ->split_node<std::tuple<typename Successors::input_type...>>;
0206
0207 #endif
0208
0209 template <typename GraphOrSet, typename Body, typename Policy>
0210 function_node(GraphOrSet&&,
0211 size_t, Body,
0212 Policy, node_priority_t = no_priority)
0213 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
0214 output_t<decltype(decide_on_callable_type<Body>(0))>,
0215 Policy>;
0216
0217 template <typename GraphOrSet, typename Body>
0218 function_node(GraphOrSet&&, size_t,
0219 Body, node_priority_t = no_priority)
0220 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
0221 output_t<decltype(decide_on_callable_type<Body>(0))>,
0222 queueing>;
0223
0224 template <typename Output>
0225 struct continue_output {
0226 using type = Output;
0227 };
0228
0229 template <>
0230 struct continue_output<void> {
0231 using type = continue_msg;
0232 };
0233
0234 template <typename T>
0235 using continue_output_t = typename continue_output<T>::type;
0236
0237 template <typename GraphOrSet, typename Body, typename Policy>
0238 continue_node(GraphOrSet&&, Body,
0239 Policy, node_priority_t = no_priority)
0240 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0241 Policy>;
0242
0243 template <typename GraphOrSet, typename Body, typename Policy>
0244 continue_node(GraphOrSet&&,
0245 int, Body,
0246 Policy, node_priority_t = no_priority)
0247 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0248 Policy>;
0249
0250 template <typename GraphOrSet, typename Body>
0251 continue_node(GraphOrSet&&,
0252 Body, node_priority_t = no_priority)
0253 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>, Policy<void>>;
0254
0255 template <typename GraphOrSet, typename Body>
0256 continue_node(GraphOrSet&&, int,
0257 Body, node_priority_t = no_priority)
0258 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0259 Policy<void>>;
0260
0261 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0262
0263 template <typename NodeSet>
0264 overwrite_node(const NodeSet&)
0265 ->overwrite_node<decide_on_set_t<NodeSet>>;
0266
0267 template <typename NodeSet>
0268 write_once_node(const NodeSet&)
0269 ->write_once_node<decide_on_set_t<NodeSet>>;
0270 #endif
0271 }
0272 }
0273 }
0274
0275 #endif
0276
0277 #endif