17 #ifndef __TBB_flow_graph_node_set_impl_H    18 #define __TBB_flow_graph_node_set_impl_H    20 #ifndef __TBB_flow_graph_H    21 #error Do not #include this internal file directly; use public TBB headers instead.    28 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET    32 #define __TBB_MSVC_DISABLE_TRAILING_DECLTYPE (_MSC_VER >= 1900)    40 class get_graph_helper {
    45     static graph& get(
const T& 
object) {
    46         return get_impl(
object, std::is_base_of<graph_node, T>());
    53         return static_cast<const graph_node*>(&
object)->my_graph;
    58         return object.graph_reference();
    62 template<
typename Order, 
typename... Nodes>
    64     typedef Order order_type;
    66     tbb::flow::tuple<Nodes&...> nodes;
    67     node_set(Nodes&... ns) : nodes(ns...) {}
    69     template <
typename... Nodes2>
    70     node_set(
const node_set<order::undefined, Nodes2...>& set) : nodes(set.nodes) {}
    72     graph& graph_reference()
 const {
    73         return get_graph_helper::get(std::get<0>(nodes));
    77 namespace alias_helpers {
    78 template <
typename T> 
using output_type = 
typename T::output_type;
    79 template <
typename T> 
using output_ports_type = 
typename T::output_ports_type;
    80 template <
typename T> 
using input_type = 
typename T::input_type;
    81 template <
typename T> 
using input_ports_type = 
typename T::input_ports_type;
    97 struct is_sender : std::is_base_of<sender<typename T::output_type>, T> {};
   100 struct is_receiver : std::is_base_of<receiver<typename T::input_type>, T> {};
   102 template <
typename Node>
   105 template <
typename... Args>
   106 struct is_async_node<
tbb::flow::interface11::async_node<Args...>> : 
std::true_type {};
   108 template<
typename FirstPredecessor, 
typename... Predecessors>
   109 node_set<order::following, FirstPredecessor, Predecessors...>
   110 follows(FirstPredecessor& first_predecessor, Predecessors&... predecessors) {
   112                                                    has_output_type<Predecessors>...>::
value),
   113                         "Not all node's predecessors has output_type typedef");
   115                         "Not all node's predecessors are senders");
   116     return node_set<order::following, FirstPredecessor, Predecessors...>(first_predecessor, predecessors...);
   119 template<
typename... Predecessors>
   120 node_set<order::following, Predecessors...>
   121 follows(node_set<order::undefined, Predecessors...>& predecessors_set) {
   123                         "Not all nodes in the set has output_type typedef");
   125                         "Not all nodes in the set are senders");
   126     return node_set<order::following, Predecessors...>(predecessors_set);
   129 template<
typename FirstSuccessor, 
typename... Successors>
   130 node_set<order::preceding, FirstSuccessor, Successors...>
   131 precedes(FirstSuccessor& first_successor, Successors&... successors) {
   133                                                     has_input_type<Successors>...>::
value),
   134                         "Not all node's successors has input_type typedef");
   136                         "Not all node's successors are receivers");
   137     return node_set<order::preceding, FirstSuccessor, Successors...>(first_successor, successors...);
   140 template<
typename... Successors>
   141 node_set<order::preceding, Successors...>
   142 precedes(node_set<order::undefined, Successors...>& successors_set) {
   144                         "Not all nodes in the set has input_type typedef");
   146                         "Not all nodes in the set are receivers");
   147     return node_set<order::preceding, Successors...>(successors_set);
   150 template <
typename Node, 
typename... Nodes>
   151 node_set<order::undefined, Node, Nodes...>
   152 make_node_set(Node& first_node, Nodes&... nodes) {
   153     return node_set<order::undefined, Node, Nodes...>(first_node, nodes...);
   157 class successor_selector {
   158     template <
typename NodeType>
   159     static auto get_impl(NodeType& node, 
std::true_type) -> decltype(input_port<I>(node)) {
   160         return input_port<I>(node);
   163     template <
typename NodeType>
   164     static NodeType& get_impl(NodeType& node, 
std::false_type) { 
return node; }
   167     template <
typename NodeType>
   168 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE   169     static auto& get(NodeType& node)
   171     static auto get(NodeType& node) -> decltype(get_impl(node, has_input_ports_type<NodeType>()))
   174         return get_impl(node, has_input_ports_type<NodeType>());
   179 class predecessor_selector {
   180     template <
typename NodeType>
   181     static auto internal_get(NodeType& node, 
std::true_type) -> decltype(output_port<I>(node)) {
   182         return output_port<I>(node);
   185     template <
typename NodeType>
   186     static NodeType& internal_get(NodeType& node, 
std::false_type) { 
return node;}
   188     template <
typename NodeType>
   189 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE   192     static auto get_impl(NodeType& node, 
std::false_type) -> decltype(internal_get(node, has_output_ports_type<NodeType>()))
   195         return internal_get(node, has_output_ports_type<NodeType>());
   198     template <
typename AsyncNode>
   199     static AsyncNode& get_impl(AsyncNode& node, 
std::true_type) { 
return node; }
   202     template <
typename NodeType>
   203 #if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE   204     static auto& get(NodeType& node)
   206     static auto get(NodeType& node) -> decltype(get_impl(node, is_async_node<NodeType>()))
   209         return get_impl(node, is_async_node<NodeType>());
   214 class make_edges_helper {
   216     template<
typename PredecessorsTuple, 
typename NodeType>
   217     static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) {
   218         make_edge(std::get<I>(predecessors), successor_selector<I>::get(node));
   219         make_edges_helper<I - 1>::connect_predecessors(predecessors, node);
   222     template<
typename SuccessorsTuple, 
typename NodeType>
   223     static void connect_successors(NodeType& node, SuccessorsTuple& successors) {
   224         make_edge(predecessor_selector<I>::get(node), std::get<I>(successors));
   225         make_edges_helper<I - 1>::connect_successors(node, successors);
   230 struct make_edges_helper<0> {
   231     template<
typename PredecessorsTuple, 
typename NodeType>
   232     static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) {
   233         make_edge(std::get<0>(predecessors), successor_selector<0>::get(node));
   236     template<
typename SuccessorsTuple, 
typename NodeType>
   237     static void connect_successors(NodeType& node, SuccessorsTuple& successors) {
   238         make_edge(predecessor_selector<0>::get(node), std::get<0>(successors));
   243 template<
typename NodeType, 
typename OrderFlagType, 
typename... Args>
   244 void make_edges(
const node_set<OrderFlagType, Args...>& 
s, NodeType& node) {
   245     const std::size_t SetSize = tbb::flow::tuple_size<decltype(
s.nodes)>
::value;
   246     make_edges_helper<SetSize - 1>::connect_predecessors(
s.nodes, node);
   249 template <
typename NodeType, 
typename OrderFlagType, 
typename... Args>
   250 void make_edges(NodeType& node, 
const node_set<OrderFlagType, Args...>& 
s) {
   251     const std::size_t SetSize = tbb::flow::tuple_size<decltype(
s.nodes)>
::value;
   252     make_edges_helper<SetSize - 1>::connect_successors(node, 
s.nodes);
   255 template <
typename NodeType, 
typename... Nodes>
   256 void make_edges_in_order(
const node_set<order::following, Nodes...>& ns, NodeType& node) {
   257     make_edges(ns, node);
   260 template <
typename NodeType, 
typename... Nodes>
   261 void make_edges_in_order(
const node_set<order::preceding, Nodes...>& ns, NodeType& node) {
   262     make_edges(node, ns);
   265 #endif // __TBB_CPP11_PRESENT   269 #endif // __TBB_flow_graph_node_set_impl_H bool_constant< true > true_type
 
bool_constant< false > false_type
 
#define __TBB_STATIC_ASSERT(condition, msg)
 
void make_edge(sender< T > &p, receiver< T > &s)
Makes an edge between a single predecessor and a single successor.
 
void const char const char int ITT_FORMAT __itt_group_sync s
 
typename supports_impl< T, void, Checks... >::type supports
 
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 value