File indexing completed on 2025-01-18 10:12:48
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 flow {
0024 namespace interface11 {
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 Input, typename Output>
0054 struct body_types<Output (*)(Input&)> : declare_body_types<Input, Output> {};
0055
0056 template <typename Input, typename Output>
0057 struct body_types<Output (*)(const Input&)> : declare_body_types<Input, Output> {};
0058
0059 template <typename T, typename Output>
0060 struct body_types<Output (T::*)(flow_control&) const> : declare_body_types<NoInputBody, Output> {};
0061
0062 template <typename T, typename Output>
0063 struct body_types<Output (T::*)(flow_control&)> : declare_body_types<NoInputBody, 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 #if TBB_USE_SOURCE_NODE_AS_ALIAS
0100 #if TBB_DEPRECATED_INPUT_NODE_BODY
0101 template <typename GraphOrSet, typename Body>
0102 source_node(GraphOrSet&&, Body)
0103 ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
0104 #else
0105 template <typename GraphOrSet, typename Body>
0106 source_node(GraphOrSet&&, Body)
0107 ->source_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
0108 #endif
0109 #else
0110 template <typename GraphOrSet, typename Body>
0111 source_node(GraphOrSet&&, Body, bool = true)
0112 ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
0113 #endif
0114
0115 #if TBB_DEPRECATED_INPUT_NODE_BODY
0116 template <typename GraphOrSet, typename Body>
0117 input_node(GraphOrSet&&, Body, bool = true)
0118 ->input_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
0119 #else
0120 template <typename GraphOrSet, typename Body>
0121 input_node(GraphOrSet&&, Body)
0122 ->input_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
0123 #endif
0124
0125 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0126
0127 template <typename NodeSet>
0128 struct decide_on_set;
0129
0130 template <typename Node, typename... Nodes>
0131 struct decide_on_set<node_set<internal::order::following, Node, Nodes...>> {
0132 using type = typename Node::output_type;
0133 };
0134
0135 template <typename Node, typename... Nodes>
0136 struct decide_on_set<node_set<internal::order::preceding, Node, Nodes...>> {
0137 using type = typename Node::input_type;
0138 };
0139
0140 template <typename NodeSet>
0141 using decide_on_set_t = typename decide_on_set<std::decay_t<NodeSet>>::type;
0142
0143 template <typename NodeSet>
0144 broadcast_node(const NodeSet&)
0145 ->broadcast_node<decide_on_set_t<NodeSet>>;
0146
0147 template <typename NodeSet>
0148 buffer_node(const NodeSet&)
0149 ->buffer_node<decide_on_set_t<NodeSet>>;
0150
0151 template <typename NodeSet>
0152 queue_node(const NodeSet&)
0153 ->queue_node<decide_on_set_t<NodeSet>>;
0154 #endif
0155
0156 template <typename GraphOrProxy, typename Sequencer>
0157 sequencer_node(GraphOrProxy&&, Sequencer)
0158 ->sequencer_node<input_t<decltype(decide_on_callable_type<Sequencer>(0))>>;
0159
0160 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0161 template <typename NodeSet, typename Compare>
0162 priority_queue_node(const NodeSet&, const Compare&)
0163 ->priority_queue_node<decide_on_set_t<NodeSet>, Compare>;
0164
0165 template <typename NodeSet>
0166 priority_queue_node(const NodeSet&)
0167 ->priority_queue_node<decide_on_set_t<NodeSet>, std::less<decide_on_set_t<NodeSet>>>;
0168 #endif
0169
0170 template <typename Key>
0171 struct join_key {
0172 using type = Key;
0173 };
0174
0175 template <typename T>
0176 struct join_key<const T&> {
0177 using type = T&;
0178 };
0179
0180 template <typename Key>
0181 using join_key_t = typename join_key<Key>::type;
0182
0183 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0184 template <typename Policy, typename... Predecessors>
0185 join_node(const node_set<internal::order::following, Predecessors...>&, Policy)
0186 ->join_node<std::tuple<typename Predecessors::output_type...>,
0187 Policy>;
0188
0189 template <typename Policy, typename Successor, typename... Successors>
0190 join_node(const node_set<internal::order::preceding, Successor, Successors...>&, Policy)
0191 ->join_node<typename Successor::input_type, Policy>;
0192
0193 template <typename... Predecessors>
0194 join_node(const node_set<internal::order::following, Predecessors...>)
0195 ->join_node<std::tuple<typename Predecessors::output_type...>,
0196 queueing>;
0197
0198 template <typename Successor, typename... Successors>
0199 join_node(const node_set<internal::order::preceding, Successor, Successors...>)
0200 ->join_node<typename Successor::input_type, queueing>;
0201 #endif
0202
0203 template <typename GraphOrProxy, typename Body, typename... Bodies>
0204 join_node(GraphOrProxy&&, Body, Bodies...)
0205 ->join_node<std::tuple<input_t<decltype(decide_on_callable_type<Body>(0))>,
0206 input_t<decltype(decide_on_callable_type<Bodies>(0))>...>,
0207 key_matching<join_key_t<output_t<decltype(decide_on_callable_type<Body>(0))>>>>;
0208
0209 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0210 template <typename... Predecessors>
0211 indexer_node(const node_set<internal::order::following, Predecessors...>&)
0212 ->indexer_node<typename Predecessors::output_type...>;
0213 #endif
0214
0215 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0216 template <typename NodeSet>
0217 limiter_node(const NodeSet&, size_t)
0218 ->limiter_node<decide_on_set_t<NodeSet>>;
0219
0220 template <typename Predecessor, typename... Predecessors>
0221 split_node(const node_set<internal::order::following, Predecessor, Predecessors...>&)
0222 ->split_node<typename Predecessor::output_type>;
0223
0224 template <typename... Successors>
0225 split_node(const node_set<internal::order::preceding, Successors...>&)
0226 ->split_node<std::tuple<typename Successors::input_type...>>;
0227
0228 #endif
0229
0230 template <typename GraphOrSet, typename Body, typename Policy>
0231 function_node(GraphOrSet&&,
0232 size_t, Body,
0233 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
0234 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
0235 output_t<decltype(decide_on_callable_type<Body>(0))>,
0236 Policy>;
0237
0238 template <typename GraphOrSet, typename Body>
0239 function_node(GraphOrSet&&, size_t,
0240 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
0241 ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
0242 output_t<decltype(decide_on_callable_type<Body>(0))>,
0243 queueing>;
0244
0245 template <typename Output>
0246 struct continue_output {
0247 using type = Output;
0248 };
0249
0250 template <>
0251 struct continue_output<void> {
0252 using type = continue_msg;
0253 };
0254
0255 template <typename T>
0256 using continue_output_t = typename continue_output<T>::type;
0257
0258 template <typename GraphOrSet, typename Body, typename Policy>
0259 continue_node(GraphOrSet&&, Body,
0260 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
0261 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0262 Policy>;
0263
0264 template <typename GraphOrSet, typename Body, typename Policy>
0265 continue_node(GraphOrSet&&,
0266 int, Body,
0267 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
0268 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0269 Policy>;
0270
0271 template <typename GraphOrSet, typename Body>
0272 continue_node(GraphOrSet&&,
0273 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
0274 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0275 internal::Policy<void>>;
0276
0277 template <typename GraphOrSet, typename Body>
0278 continue_node(GraphOrSet&&, int,
0279 __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
0280 ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
0281 internal::Policy<void>>;
0282
0283 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
0284
0285 template <typename NodeSet>
0286 overwrite_node(const NodeSet&)
0287 ->overwrite_node<decide_on_set_t<NodeSet>>;
0288
0289 template <typename NodeSet>
0290 write_once_node(const NodeSet&)
0291 ->write_once_node<decide_on_set_t<NodeSet>>;
0292 #endif
0293 }
0294 }
0295 }
0296
0297 #endif
0298 #endif