_flow_graph_nodes_deduction.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. Copyright (c) 2005-2020 Intel Corporation
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #ifndef __TBB_flow_graph_nodes_deduction_H
  14. #define __TBB_flow_graph_nodes_deduction_H
  15. #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
  16. namespace tbb {
  17. namespace flow {
  18. namespace interface11 {
  19. template <typename Input, typename Output>
  20. struct declare_body_types {
  21. using input_type = Input;
  22. using output_type = Output;
  23. };
  24. struct NoInputBody {};
  25. template <typename Output>
  26. struct declare_body_types<NoInputBody, Output> {
  27. using output_type = Output;
  28. };
  29. template <typename T> struct body_types;
  30. template <typename T, typename Input, typename Output>
  31. struct body_types<Output (T::*)(const Input&) const> : declare_body_types<Input, Output> {};
  32. template <typename T, typename Input, typename Output>
  33. struct body_types<Output (T::*)(const Input&)> : declare_body_types<Input, Output> {};
  34. template <typename T, typename Input, typename Output>
  35. struct body_types<Output (T::*)(Input&) const> : declare_body_types<Input, Output> {};
  36. template <typename T, typename Input, typename Output>
  37. struct body_types<Output (T::*)(Input&)> : declare_body_types<Input, Output> {};
  38. template <typename Input, typename Output>
  39. struct body_types<Output (*)(Input&)> : declare_body_types<Input, Output> {};
  40. template <typename Input, typename Output>
  41. struct body_types<Output (*)(const Input&)> : declare_body_types<Input, Output> {};
  42. template <typename T, typename Output>
  43. struct body_types<Output (T::*)(flow_control&) const> : declare_body_types<NoInputBody, Output> {};
  44. template <typename T, typename Output>
  45. struct body_types<Output (T::*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
  46. template <typename Output>
  47. struct body_types<Output (*)(flow_control&)> : declare_body_types<NoInputBody, Output> {};
  48. template <typename Body>
  49. using input_t = typename body_types<Body>::input_type;
  50. template <typename Body>
  51. using output_t = typename body_types<Body>::output_type;
  52. template <typename T, typename Input, typename Output>
  53. auto decide_on_operator_overload(Output (T::*name)(const Input&) const)->decltype(name);
  54. template <typename T, typename Input, typename Output>
  55. auto decide_on_operator_overload(Output (T::*name)(const Input&))->decltype(name);
  56. template <typename T, typename Input, typename Output>
  57. auto decide_on_operator_overload(Output (T::*name)(Input&) const)->decltype(name);
  58. template <typename T, typename Input, typename Output>
  59. auto decide_on_operator_overload(Output (T::*name)(Input&))->decltype(name);
  60. template <typename Input, typename Output>
  61. auto decide_on_operator_overload(Output (*name)(const Input&))->decltype(name);
  62. template <typename Input, typename Output>
  63. auto decide_on_operator_overload(Output (*name)(Input&))->decltype(name);
  64. template <typename Body>
  65. decltype(decide_on_operator_overload(&Body::operator())) decide_on_callable_type(int);
  66. template <typename Body>
  67. decltype(decide_on_operator_overload(std::declval<Body>())) decide_on_callable_type(...);
  68. // Deduction guides for Flow Graph nodes
  69. #if TBB_USE_SOURCE_NODE_AS_ALIAS
  70. #if TBB_DEPRECATED_INPUT_NODE_BODY
  71. template <typename GraphOrSet, typename Body>
  72. source_node(GraphOrSet&&, Body)
  73. ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
  74. #else
  75. template <typename GraphOrSet, typename Body>
  76. source_node(GraphOrSet&&, Body)
  77. ->source_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
  78. #endif // TBB_DEPRECATED_INPUT_NODE_BODY
  79. #else
  80. template <typename GraphOrSet, typename Body>
  81. source_node(GraphOrSet&&, Body, bool = true)
  82. ->source_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
  83. #endif
  84. #if TBB_DEPRECATED_INPUT_NODE_BODY
  85. template <typename GraphOrSet, typename Body>
  86. input_node(GraphOrSet&&, Body, bool = true)
  87. ->input_node<input_t<decltype(decide_on_callable_type<Body>(0))>>;
  88. #else
  89. template <typename GraphOrSet, typename Body>
  90. input_node(GraphOrSet&&, Body)
  91. ->input_node<output_t<decltype(decide_on_callable_type<Body>(0))>>;
  92. #endif
  93. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  94. template <typename NodeSet>
  95. struct decide_on_set;
  96. template <typename Node, typename... Nodes>
  97. struct decide_on_set<node_set<internal::order::following, Node, Nodes...>> {
  98. using type = typename Node::output_type;
  99. };
  100. template <typename Node, typename... Nodes>
  101. struct decide_on_set<node_set<internal::order::preceding, Node, Nodes...>> {
  102. using type = typename Node::input_type;
  103. };
  104. template <typename NodeSet>
  105. using decide_on_set_t = typename decide_on_set<std::decay_t<NodeSet>>::type;
  106. template <typename NodeSet>
  107. broadcast_node(const NodeSet&)
  108. ->broadcast_node<decide_on_set_t<NodeSet>>;
  109. template <typename NodeSet>
  110. buffer_node(const NodeSet&)
  111. ->buffer_node<decide_on_set_t<NodeSet>>;
  112. template <typename NodeSet>
  113. queue_node(const NodeSet&)
  114. ->queue_node<decide_on_set_t<NodeSet>>;
  115. #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  116. template <typename GraphOrProxy, typename Sequencer>
  117. sequencer_node(GraphOrProxy&&, Sequencer)
  118. ->sequencer_node<input_t<decltype(decide_on_callable_type<Sequencer>(0))>>;
  119. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  120. template <typename NodeSet, typename Compare>
  121. priority_queue_node(const NodeSet&, const Compare&)
  122. ->priority_queue_node<decide_on_set_t<NodeSet>, Compare>;
  123. template <typename NodeSet>
  124. priority_queue_node(const NodeSet&)
  125. ->priority_queue_node<decide_on_set_t<NodeSet>, std::less<decide_on_set_t<NodeSet>>>;
  126. #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  127. template <typename Key>
  128. struct join_key {
  129. using type = Key;
  130. };
  131. template <typename T>
  132. struct join_key<const T&> {
  133. using type = T&;
  134. };
  135. template <typename Key>
  136. using join_key_t = typename join_key<Key>::type;
  137. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  138. template <typename Policy, typename... Predecessors>
  139. join_node(const node_set<internal::order::following, Predecessors...>&, Policy)
  140. ->join_node<std::tuple<typename Predecessors::output_type...>,
  141. Policy>;
  142. template <typename Policy, typename Successor, typename... Successors>
  143. join_node(const node_set<internal::order::preceding, Successor, Successors...>&, Policy)
  144. ->join_node<typename Successor::input_type, Policy>;
  145. template <typename... Predecessors>
  146. join_node(const node_set<internal::order::following, Predecessors...>)
  147. ->join_node<std::tuple<typename Predecessors::output_type...>,
  148. queueing>;
  149. template <typename Successor, typename... Successors>
  150. join_node(const node_set<internal::order::preceding, Successor, Successors...>)
  151. ->join_node<typename Successor::input_type, queueing>;
  152. #endif
  153. template <typename GraphOrProxy, typename Body, typename... Bodies>
  154. join_node(GraphOrProxy&&, Body, Bodies...)
  155. ->join_node<std::tuple<input_t<decltype(decide_on_callable_type<Body>(0))>,
  156. input_t<decltype(decide_on_callable_type<Bodies>(0))>...>,
  157. key_matching<join_key_t<output_t<decltype(decide_on_callable_type<Body>(0))>>>>;
  158. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  159. template <typename... Predecessors>
  160. indexer_node(const node_set<internal::order::following, Predecessors...>&)
  161. ->indexer_node<typename Predecessors::output_type...>;
  162. #endif
  163. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  164. template <typename NodeSet>
  165. limiter_node(const NodeSet&, size_t)
  166. ->limiter_node<decide_on_set_t<NodeSet>>;
  167. template <typename Predecessor, typename... Predecessors>
  168. split_node(const node_set<internal::order::following, Predecessor, Predecessors...>&)
  169. ->split_node<typename Predecessor::output_type>;
  170. template <typename... Successors>
  171. split_node(const node_set<internal::order::preceding, Successors...>&)
  172. ->split_node<std::tuple<typename Successors::input_type...>>;
  173. #endif
  174. template <typename GraphOrSet, typename Body, typename Policy>
  175. function_node(GraphOrSet&&,
  176. size_t, Body,
  177. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
  178. ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
  179. output_t<decltype(decide_on_callable_type<Body>(0))>,
  180. Policy>;
  181. template <typename GraphOrSet, typename Body>
  182. function_node(GraphOrSet&&, size_t,
  183. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
  184. ->function_node<input_t<decltype(decide_on_callable_type<Body>(0))>,
  185. output_t<decltype(decide_on_callable_type<Body>(0))>,
  186. queueing>;
  187. template <typename Output>
  188. struct continue_output {
  189. using type = Output;
  190. };
  191. template <>
  192. struct continue_output<void> {
  193. using type = continue_msg;
  194. };
  195. template <typename T>
  196. using continue_output_t = typename continue_output<T>::type;
  197. template <typename GraphOrSet, typename Body, typename Policy>
  198. continue_node(GraphOrSet&&, Body,
  199. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
  200. ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
  201. Policy>;
  202. template <typename GraphOrSet, typename Body, typename Policy>
  203. continue_node(GraphOrSet&&,
  204. int, Body,
  205. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority))
  206. ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
  207. Policy>;
  208. template <typename GraphOrSet, typename Body>
  209. continue_node(GraphOrSet&&,
  210. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
  211. ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
  212. internal::Policy<void>>;
  213. template <typename GraphOrSet, typename Body>
  214. continue_node(GraphOrSet&&, int,
  215. __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority))
  216. ->continue_node<continue_output_t<std::invoke_result_t<Body, continue_msg>>,
  217. internal::Policy<void>>;
  218. #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  219. template <typename NodeSet>
  220. overwrite_node(const NodeSet&)
  221. ->overwrite_node<decide_on_set_t<NodeSet>>;
  222. template <typename NodeSet>
  223. write_once_node(const NodeSet&)
  224. ->write_once_node<decide_on_set_t<NodeSet>>;
  225. #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
  226. } // namespace interfaceX
  227. } // namespace flow
  228. } // namespace tbb
  229. #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
  230. #endif // __TBB_flow_graph_nodes_deduction_H