Compare commits

...
Author SHA1 Message Date
kboyarinov 0baaad609a Fix indexer_node implementation, add test 2022-10-26 06:36:29 -05:00
kboyarinov cb8fa21a84 Get rid of C++03 rudiments 2022-10-24 08:52:54 -05:00
5 changed files with 164 additions and 996 deletions
@@ -203,146 +203,23 @@
broadcast_cache<output_type, null_rw_mutex> my_successors;
}; //indexer_node_base
template<int N, typename InputTuple> struct input_types;
template<typename InputTuple>
struct input_types<1, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef tagged_msg<size_t, first_type > type;
};
template<typename InputTuple>
struct input_types<2, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef tagged_msg<size_t, first_type, second_type> type;
};
template<typename InputTuple>
struct input_types<3, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef tagged_msg<size_t, first_type, second_type, third_type> type;
};
template<typename InputTuple>
struct input_types<4, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type> type;
};
template<typename InputTuple>
struct input_types<5, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type> type;
};
template<typename InputTuple>
struct input_types<6, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type, sixth_type> type;
};
template<typename InputTuple>
struct input_types<7, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type, sixth_type,
seventh_type> type;
};
template<typename InputTuple>
struct input_types<8, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type, sixth_type,
seventh_type, eighth_type> type;
};
template<typename InputTuple>
struct input_types<9, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type, sixth_type,
seventh_type, eighth_type, nineth_type> type;
};
template<typename InputTuple>
struct input_types<10, InputTuple> {
typedef typename std::tuple_element<0, InputTuple>::type first_type;
typedef typename std::tuple_element<1, InputTuple>::type second_type;
typedef typename std::tuple_element<2, InputTuple>::type third_type;
typedef typename std::tuple_element<3, InputTuple>::type fourth_type;
typedef typename std::tuple_element<4, InputTuple>::type fifth_type;
typedef typename std::tuple_element<5, InputTuple>::type sixth_type;
typedef typename std::tuple_element<6, InputTuple>::type seventh_type;
typedef typename std::tuple_element<7, InputTuple>::type eighth_type;
typedef typename std::tuple_element<8, InputTuple>::type nineth_type;
typedef typename std::tuple_element<9, InputTuple>::type tenth_type;
typedef tagged_msg<size_t, first_type, second_type, third_type,
fourth_type, fifth_type, sixth_type,
seventh_type, eighth_type, nineth_type,
tenth_type> type;
};
// type generators
template<typename OutputTuple>
struct indexer_types : public input_types<std::tuple_size<OutputTuple>::value, OutputTuple> {
static const int N = std::tuple_size<OutputTuple>::value;
typedef typename input_types<N, OutputTuple>::type output_type;
typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
typedef indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
typedef indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
template<typename T0, typename... TN>
struct indexer_types {
using output_type = tagged_msg<std::size_t, T0, TN...>;
using input_ports_type = std::tuple<indexer_input_port<T0>, indexer_input_port<TN>...>;
using indexer_FE_type = indexer_node_FE<input_ports_type, output_type, std::tuple<T0, TN...>>;
using indexer_base_type = indexer_node_base<input_ports_type, output_type, std::tuple<T0, TN...>>;
};
template<class OutputTuple>
class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
template<typename T0, typename... TN>
class unfolded_indexer_node : public indexer_types<T0, TN...>::indexer_base_type {
public:
typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
typedef OutputTuple tuple_types;
typedef typename indexer_types<OutputTuple>::output_type output_type;
typedef std::tuple<T0, TN...> tuple_types;
typedef typename indexer_types<T0, TN...>::input_ports_type input_ports_type;
typedef typename indexer_types<T0, TN...>::output_type output_type;
private:
typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
typedef typename indexer_types<T0, TN...>::indexer_base_type base_type;
public:
unfolded_indexer_node(graph& g) : base_type(g) {}
unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
+42 -468
View File
@@ -1192,38 +1192,22 @@
}; // join_node_base
// join base class type generator
template<int N, template<class> class PT, typename OutputTuple, typename JP>
template<template<class> class PT, typename OutputTuple, typename JP>
struct join_base {
typedef join_node_base<JP, typename wrap_tuple_elements<N,PT,OutputTuple>::type, OutputTuple> type;
typedef join_node_base<JP, typename wrap_tuple_elements<PT,OutputTuple>::type, OutputTuple> type;
};
template<int N, typename OutputTuple, typename K, typename KHash>
struct join_base<N, key_matching_port, OutputTuple, key_matching<K,KHash> > {
template<typename OutputTuple, typename K, typename KHash>
struct join_base<key_matching_port, OutputTuple, key_matching<K,KHash> > {
typedef key_matching<K, KHash> key_traits_type;
typedef K key_type;
typedef KHash key_hash_compare;
typedef join_node_base< key_traits_type,
// ports type
typename wrap_key_tuple_elements<N,key_matching_port,key_traits_type,OutputTuple>::type,
typename wrap_key_tuple_elements<key_matching_port,key_traits_type,OutputTuple>::type,
OutputTuple > type;
};
//! unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type
// using tuple_element. The class PT is the port type (reserving_port, queueing_port, key_matching_port)
// and should match the typename.
template<int N, template<class> class PT, typename OutputTuple, typename JP>
class unfolded_join_node : public join_base<N,PT,OutputTuple,JP>::type {
public:
typedef typename wrap_tuple_elements<N, PT, OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<JP, input_ports_type, output_type > base_type;
public:
unfolded_join_node(graph &g) : base_type(g) {}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
template <typename K, typename T>
struct key_from_message_body {
@@ -1239,463 +1223,53 @@
}
};
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
//! unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type
// using tuple_element. The class PT is the port type (reserving_port, queueing_port, key_matching_port)
// and should match the typename.
template<template<class> class PT, typename OutputTuple, typename JP>
class unfolded_join_node : public join_base<PT, OutputTuple, JP>::type {
public:
using input_ports_type = typename wrap_tuple_elements<PT, OutputTuple>::type;
using output_type = OutputTuple;
private:
using base_type = join_node_base<JP, input_ports_type, output_type>;
public:
unfolded_join_node(graph& g) : base_type(g) {}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
// key_matching unfolded_join_node. This must be a separate specialization because the constructors
// differ.
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<2,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<2,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
template<typename K, typename KHash, typename...Types>
class unfolded_join_node<key_matching_port, std::tuple<Types...>, key_matching<K, KHash>>
: public join_base<key_matching_port, std::tuple<Types...>, key_matching<K, KHash>>::type
{
public:
typedef typename wrap_key_tuple_elements<2,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
using input_ports_type = typename wrap_key_tuple_elements<key_matching_port,
key_matching<K, KHash>,
std::tuple<Types...>>::type;
using output_type = std::tuple<Types...>;
private:
typedef join_node_base<key_matching<K,KHash>, input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef std::tuple< f0_p, f1_p > func_initializer_type;
using base_type = join_node_base<key_matching<K, KHash>, input_ports_type, output_type>;
using func_initializer_type = std::tuple<type_to_key_function_body<Types, K>*...>;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1>
unfolded_join_node(graph &g, Body0 body0, Body1 body1) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 2, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<3,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<3,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
public:
typedef typename wrap_key_tuple_elements<3,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash>, input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef std::tuple< f0_p, f1_p, f2_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 3, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<4,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<4,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
public:
typedef typename wrap_key_tuple_elements<4,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash>, input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 4, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<5,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<5,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
public:
typedef typename wrap_key_tuple_elements<5,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 5, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#if __TBB_VARIADIC_MAX >= 6
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<6,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<6,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
typedef typename std::tuple_element<5, OutputTuple>::type T5;
public:
typedef typename wrap_key_tuple_elements<6,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef type_to_key_function_body<T5, K> *f5_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>()),
new type_to_key_function_body_leaf<T5, K, key_from_message_body<K,T5> >(key_from_message_body<K,T5>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4, typename Body5>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, Body5 body5)
: base_type(g, func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4),
new type_to_key_function_body_leaf<T5, K, Body5>(body5)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 6, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
unfolded_join_node(graph &g)
: base_type(g,
func_initializer_type(new type_to_key_function_body_leaf<Types, K,
key_from_message_body<K, Types>>(key_from_message_body<K, Types>())...))
{}
#endif
#if __TBB_VARIADIC_MAX >= 7
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<7,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<7,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
typedef typename std::tuple_element<5, OutputTuple>::type T5;
typedef typename std::tuple_element<6, OutputTuple>::type T6;
public:
typedef typename wrap_key_tuple_elements<7,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef type_to_key_function_body<T5, K> *f5_p;
typedef type_to_key_function_body<T6, K> *f6_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>()),
new type_to_key_function_body_leaf<T5, K, key_from_message_body<K,T5> >(key_from_message_body<K,T5>()),
new type_to_key_function_body_leaf<T6, K, key_from_message_body<K,T6> >(key_from_message_body<K,T6>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
typename Body5, typename Body6>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
Body5 body5, Body6 body6) : base_type(g, func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4),
new type_to_key_function_body_leaf<T5, K, Body5>(body5),
new type_to_key_function_body_leaf<T6, K, Body6>(body6)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 7, "wrong number of body initializers");
}
template<typename... Bodies>
unfolded_join_node(graph &g, Bodies... bodies)
: base_type(g,
func_initializer_type(new type_to_key_function_body_leaf<Types, K, Bodies>(bodies)...))
{}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#endif
#if __TBB_VARIADIC_MAX >= 8
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<8,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<8,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
typedef typename std::tuple_element<5, OutputTuple>::type T5;
typedef typename std::tuple_element<6, OutputTuple>::type T6;
typedef typename std::tuple_element<7, OutputTuple>::type T7;
public:
typedef typename wrap_key_tuple_elements<8,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef type_to_key_function_body<T5, K> *f5_p;
typedef type_to_key_function_body<T6, K> *f6_p;
typedef type_to_key_function_body<T7, K> *f7_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>()),
new type_to_key_function_body_leaf<T5, K, key_from_message_body<K,T5> >(key_from_message_body<K,T5>()),
new type_to_key_function_body_leaf<T6, K, key_from_message_body<K,T6> >(key_from_message_body<K,T6>()),
new type_to_key_function_body_leaf<T7, K, key_from_message_body<K,T7> >(key_from_message_body<K,T7>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
typename Body5, typename Body6, typename Body7>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
Body5 body5, Body6 body6, Body7 body7) : base_type(g, func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4),
new type_to_key_function_body_leaf<T5, K, Body5>(body5),
new type_to_key_function_body_leaf<T6, K, Body6>(body6),
new type_to_key_function_body_leaf<T7, K, Body7>(body7)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 8, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#endif
#if __TBB_VARIADIC_MAX >= 9
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<9,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<9,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
typedef typename std::tuple_element<5, OutputTuple>::type T5;
typedef typename std::tuple_element<6, OutputTuple>::type T6;
typedef typename std::tuple_element<7, OutputTuple>::type T7;
typedef typename std::tuple_element<8, OutputTuple>::type T8;
public:
typedef typename wrap_key_tuple_elements<9,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef type_to_key_function_body<T5, K> *f5_p;
typedef type_to_key_function_body<T6, K> *f6_p;
typedef type_to_key_function_body<T7, K> *f7_p;
typedef type_to_key_function_body<T8, K> *f8_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>()),
new type_to_key_function_body_leaf<T5, K, key_from_message_body<K,T5> >(key_from_message_body<K,T5>()),
new type_to_key_function_body_leaf<T6, K, key_from_message_body<K,T6> >(key_from_message_body<K,T6>()),
new type_to_key_function_body_leaf<T7, K, key_from_message_body<K,T7> >(key_from_message_body<K,T7>()),
new type_to_key_function_body_leaf<T8, K, key_from_message_body<K,T8> >(key_from_message_body<K,T8>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
typename Body5, typename Body6, typename Body7, typename Body8>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
Body5 body5, Body6 body6, Body7 body7, Body8 body8) : base_type(g, func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4),
new type_to_key_function_body_leaf<T5, K, Body5>(body5),
new type_to_key_function_body_leaf<T6, K, Body6>(body6),
new type_to_key_function_body_leaf<T7, K, Body7>(body7),
new type_to_key_function_body_leaf<T8, K, Body8>(body8)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 9, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#endif
#if __TBB_VARIADIC_MAX >= 10
template<typename OutputTuple, typename K, typename KHash>
class unfolded_join_node<10,key_matching_port,OutputTuple,key_matching<K,KHash> > : public
join_base<10,key_matching_port,OutputTuple,key_matching<K,KHash> >::type {
typedef typename std::tuple_element<0, OutputTuple>::type T0;
typedef typename std::tuple_element<1, OutputTuple>::type T1;
typedef typename std::tuple_element<2, OutputTuple>::type T2;
typedef typename std::tuple_element<3, OutputTuple>::type T3;
typedef typename std::tuple_element<4, OutputTuple>::type T4;
typedef typename std::tuple_element<5, OutputTuple>::type T5;
typedef typename std::tuple_element<6, OutputTuple>::type T6;
typedef typename std::tuple_element<7, OutputTuple>::type T7;
typedef typename std::tuple_element<8, OutputTuple>::type T8;
typedef typename std::tuple_element<9, OutputTuple>::type T9;
public:
typedef typename wrap_key_tuple_elements<10,key_matching_port,key_matching<K,KHash>,OutputTuple>::type input_ports_type;
typedef OutputTuple output_type;
private:
typedef join_node_base<key_matching<K,KHash> , input_ports_type, output_type > base_type;
typedef type_to_key_function_body<T0, K> *f0_p;
typedef type_to_key_function_body<T1, K> *f1_p;
typedef type_to_key_function_body<T2, K> *f2_p;
typedef type_to_key_function_body<T3, K> *f3_p;
typedef type_to_key_function_body<T4, K> *f4_p;
typedef type_to_key_function_body<T5, K> *f5_p;
typedef type_to_key_function_body<T6, K> *f6_p;
typedef type_to_key_function_body<T7, K> *f7_p;
typedef type_to_key_function_body<T8, K> *f8_p;
typedef type_to_key_function_body<T9, K> *f9_p;
typedef std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type;
public:
#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
unfolded_join_node(graph &g) : base_type(g,
func_initializer_type(
new type_to_key_function_body_leaf<T0, K, key_from_message_body<K,T0> >(key_from_message_body<K,T0>()),
new type_to_key_function_body_leaf<T1, K, key_from_message_body<K,T1> >(key_from_message_body<K,T1>()),
new type_to_key_function_body_leaf<T2, K, key_from_message_body<K,T2> >(key_from_message_body<K,T2>()),
new type_to_key_function_body_leaf<T3, K, key_from_message_body<K,T3> >(key_from_message_body<K,T3>()),
new type_to_key_function_body_leaf<T4, K, key_from_message_body<K,T4> >(key_from_message_body<K,T4>()),
new type_to_key_function_body_leaf<T5, K, key_from_message_body<K,T5> >(key_from_message_body<K,T5>()),
new type_to_key_function_body_leaf<T6, K, key_from_message_body<K,T6> >(key_from_message_body<K,T6>()),
new type_to_key_function_body_leaf<T7, K, key_from_message_body<K,T7> >(key_from_message_body<K,T7>()),
new type_to_key_function_body_leaf<T8, K, key_from_message_body<K,T8> >(key_from_message_body<K,T8>()),
new type_to_key_function_body_leaf<T9, K, key_from_message_body<K,T9> >(key_from_message_body<K,T9>())
) ) {
}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
typename Body5, typename Body6, typename Body7, typename Body8, typename Body9>
unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
Body5 body5, Body6 body6, Body7 body7, Body8 body8, Body9 body9) : base_type(g, func_initializer_type(
new type_to_key_function_body_leaf<T0, K, Body0>(body0),
new type_to_key_function_body_leaf<T1, K, Body1>(body1),
new type_to_key_function_body_leaf<T2, K, Body2>(body2),
new type_to_key_function_body_leaf<T3, K, Body3>(body3),
new type_to_key_function_body_leaf<T4, K, Body4>(body4),
new type_to_key_function_body_leaf<T5, K, Body5>(body5),
new type_to_key_function_body_leaf<T6, K, Body6>(body6),
new type_to_key_function_body_leaf<T7, K, Body7>(body7),
new type_to_key_function_body_leaf<T8, K, Body8>(body8),
new type_to_key_function_body_leaf<T9, K, Body9>(body9)
) ) {
static_assert(std::tuple_size<OutputTuple>::value == 10, "wrong number of body initializers");
}
unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
};
#endif
//! templated function to refer to input ports of the join node
template<size_t N, typename JNT>
@@ -43,21 +43,21 @@ struct KeyTrait {
};
// wrap each element of a tuple in a template, and make a tuple of the result.
template<int N, template<class> class PT, typename TypeTuple>
template<template<class> class PT, typename TypeTuple>
struct wrap_tuple_elements;
// A wrapper that generates the traits needed for each port of a key-matching join,
// and the type of the tuple of input ports.
template<int N, template<class> class PT, typename KeyTraits, typename TypeTuple>
template<template<class> class PT, typename KeyTraits, typename TypeTuple>
struct wrap_key_tuple_elements;
template<int N, template<class> class PT, typename... Args>
struct wrap_tuple_elements<N, PT, std::tuple<Args...> >{
template<template<class> class PT, typename... Args>
struct wrap_tuple_elements<PT, std::tuple<Args...> >{
typedef typename std::tuple<PT<Args>... > type;
};
template<int N, template<class> class PT, typename KeyTraits, typename... Args>
struct wrap_key_tuple_elements<N, PT, KeyTraits, std::tuple<Args...> > {
template<template<class> class PT, typename KeyTraits, typename... Args>
struct wrap_key_tuple_elements<PT, KeyTraits, std::tuple<Args...> > {
typedef typename KeyTraits::key_type K;
typedef typename KeyTraits::hash_compare_type KHash;
typedef typename std::tuple<PT<KeyTrait<K, KHash, Args> >... > type;
@@ -293,31 +293,11 @@ struct do_if<T, false> {
// the object can only be tested for type, and a read-only reference can be fetched by cast_to<T>().
using tbb::detail::punned_cast;
struct tagged_null_type {};
template<typename TagType, typename T0, typename T1=tagged_null_type, typename T2=tagged_null_type, typename T3=tagged_null_type,
typename T4=tagged_null_type, typename T5=tagged_null_type, typename T6=tagged_null_type,
typename T7=tagged_null_type, typename T8=tagged_null_type, typename T9=tagged_null_type>
class tagged_msg {
typedef std::tuple<T0, T1, T2, T3, T4
//TODO: Should we reject lists longer than a tuple can hold?
#if __TBB_VARIADIC_MAX >= 6
, T5
#endif
#if __TBB_VARIADIC_MAX >= 7
, T6
#endif
#if __TBB_VARIADIC_MAX >= 8
, T7
#endif
#if __TBB_VARIADIC_MAX >= 9
, T8
#endif
#if __TBB_VARIADIC_MAX >= 10
, T9
#endif
> Tuple;
private:
template<typename TagType, typename T0, typename... TN>
class tagged_msg {
using Tuple = std::tuple<T0, TN...>;
class variant {
static const size_t N = std::tuple_size<Tuple>::value;
typedef typename pick_tuple_max<N, Tuple, alignment_of>::type AlignType;
@@ -373,7 +353,6 @@ private:
TagType my_tag;
variant my_msg;
public:
tagged_msg(): my_tag(TagType(~0)), my_msg(){}
@@ -393,7 +372,7 @@ public:
bool is_a() const {return my_msg.template variant_is_a<V>();}
bool is_default_constructed() const {return my_msg.variant_is_default_constructed();}
}; //class tagged_msg
};
// template to simplify cast and test for tagged_msg in template contexts
template<typename V, typename T>
+19 -361
View File
@@ -856,7 +856,6 @@ class multifunction_node :
<
Input,
typename wrap_tuple_elements<
std::tuple_size<Output>::value, // #elements in tuple
multifunction_output, // wrap this around each element
Output // the tuple providing the types
>::type,
@@ -871,7 +870,7 @@ protected:
public:
typedef Input input_type;
typedef null_type output_type;
typedef typename wrap_tuple_elements<N,multifunction_output, Output>::type output_ports_type;
typedef typename wrap_tuple_elements<multifunction_output, Output>::type output_ports_type;
typedef multifunction_input<
input_type, output_ports_type, Policy, internals_allocator> input_impl_type;
typedef function_input_queue<input_type, internals_allocator> input_queue_type;
@@ -932,7 +931,6 @@ class split_node : public graph_node, public receiver<TupleType> {
public:
typedef TupleType input_type;
typedef typename wrap_tuple_elements<
N, // #elements in tuple
multifunction_output, // wrap this around each element
TupleType // the tuple providing the types
>::type output_ports_type;
@@ -2138,10 +2136,10 @@ protected:
template<typename OutputTuple, typename JP=queueing> class join_node;
template<typename OutputTuple>
class join_node<OutputTuple,reserving>: public unfolded_join_node<std::tuple_size<OutputTuple>::value, reserving_port, OutputTuple, reserving> {
class join_node<OutputTuple,reserving>: public unfolded_join_node<reserving_port, OutputTuple, reserving> {
private:
static const int N = std::tuple_size<OutputTuple>::value;
typedef unfolded_join_node<N, reserving_port, OutputTuple, reserving> unfolded_type;
typedef unfolded_join_node<reserving_port, OutputTuple, reserving> unfolded_type;
public:
typedef OutputTuple output_type;
typedef typename unfolded_type::input_ports_type input_ports_type;
@@ -2165,10 +2163,10 @@ public:
};
template<typename OutputTuple>
class join_node<OutputTuple,queueing>: public unfolded_join_node<std::tuple_size<OutputTuple>::value, queueing_port, OutputTuple, queueing> {
class join_node<OutputTuple,queueing>: public unfolded_join_node<queueing_port, OutputTuple, queueing> {
private:
static const int N = std::tuple_size<OutputTuple>::value;
typedef unfolded_join_node<N, queueing_port, OutputTuple, queueing> unfolded_type;
typedef unfolded_join_node<queueing_port, OutputTuple, queueing> unfolded_type;
public:
typedef OutputTuple output_type;
typedef typename unfolded_type::input_ports_type input_ports_type;
@@ -2210,11 +2208,10 @@ concept join_node_functions = requires {
// template for key_matching join_node
// tag_matching join_node is a specialization of key_matching, and is source-compatible.
template<typename OutputTuple, typename K, typename KHash>
class join_node<OutputTuple, key_matching<K, KHash> > : public unfolded_join_node<std::tuple_size<OutputTuple>::value,
key_matching_port, OutputTuple, key_matching<K,KHash> > {
class join_node<OutputTuple, key_matching<K, KHash> > : public unfolded_join_node<key_matching_port, OutputTuple, key_matching<K,KHash> > {
private:
static const int N = std::tuple_size<OutputTuple>::value;
typedef unfolded_join_node<N, key_matching_port, OutputTuple, key_matching<K,KHash> > unfolded_type;
typedef unfolded_join_node<key_matching_port, OutputTuple, key_matching<K,KHash> > unfolded_type;
public:
typedef OutputTuple output_type;
typedef typename unfolded_type::input_ports_type input_ports_type;
@@ -2223,81 +2220,12 @@ public:
join_node(graph &g) : unfolded_type(g) {}
#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
template<typename __TBB_B0, typename __TBB_B1>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) {
template<typename... Bodies, typename = typename std::enable_if<sizeof...(Bodies) == N>>
__TBB_requires(join_node_functions<OutputTuple, K, Bodies...>)
__TBB_NOINLINE_SYM join_node(graph& g, Bodies... bodies) : unfolded_type(g, bodies...) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) :
unfolded_type(g, b0, b1, b2, b3, b4) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_VARIADIC_MAX >= 6
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
typename __TBB_B5>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4, __TBB_B5>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5) :
unfolded_type(g, b0, b1, b2, b3, b4, b5) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#endif
#if __TBB_VARIADIC_MAX >= 7
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
typename __TBB_B5, typename __TBB_B6>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4, __TBB_B5, __TBB_B6>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) :
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#endif
#if __TBB_VARIADIC_MAX >= 8
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
typename __TBB_B5, typename __TBB_B6, typename __TBB_B7>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4, __TBB_B5, __TBB_B6, __TBB_B7>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#endif
#if __TBB_VARIADIC_MAX >= 9
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4, __TBB_B5, __TBB_B6, __TBB_B7, __TBB_B8>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#endif
#if __TBB_VARIADIC_MAX >= 10
template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8, typename __TBB_B9>
__TBB_requires(join_node_functions<OutputTuple, K, __TBB_B0, __TBB_B1, __TBB_B2, __TBB_B3, __TBB_B4, __TBB_B5, __TBB_B6, __TBB_B7, __TBB_B8, __TBB_B9>)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#endif
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <
@@ -2324,20 +2252,16 @@ public:
// indexer node
#include "detail/_flow_graph_indexer_impl.h"
// TODO: Implement interface with variadic template or tuple
template<typename T0, typename T1=null_type, typename T2=null_type, typename T3=null_type,
typename T4=null_type, typename T5=null_type, typename T6=null_type,
typename T7=null_type, typename T8=null_type, typename T9=null_type> class indexer_node;
//indexer node specializations
template<typename T0>
class indexer_node<T0> : public unfolded_indexer_node<std::tuple<T0> > {
template <typename T0, typename... TN>
__TBB_requires(std::copy_constructible<T0> &&
(... && std::copy_constructible<TN>))
class indexer_node : public unfolded_indexer_node<T0, TN...> {
private:
static const int N = 1;
static constexpr std::size_t N = sizeof...(TN) + 1;
public:
typedef std::tuple<T0> InputTuple;
typedef tagged_msg<size_t, T0> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
using output_type = tagged_msg<std::size_t, T0, TN...>;
using unfolded_type = unfolded_indexer_node<T0, TN...>;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
@@ -2355,273 +2279,7 @@ public:
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
template<typename T0, typename T1>
class indexer_node<T0, T1> : public unfolded_indexer_node<std::tuple<T0, T1> > {
private:
static const int N = 2;
public:
typedef std::tuple<T0, T1> InputTuple;
typedef tagged_msg<size_t, T0, T1> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
template<typename T0, typename T1, typename T2>
class indexer_node<T0, T1, T2> : public unfolded_indexer_node<std::tuple<T0, T1, T2> > {
private:
static const int N = 3;
public:
typedef std::tuple<T0, T1, T2> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
template<typename T0, typename T1, typename T2, typename T3>
class indexer_node<T0, T1, T2, T3> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3> > {
private:
static const int N = 4;
public:
typedef std::tuple<T0, T1, T2, T3> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
template<typename T0, typename T1, typename T2, typename T3, typename T4>
class indexer_node<T0, T1, T2, T3, T4> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4> > {
private:
static const int N = 5;
public:
typedef std::tuple<T0, T1, T2, T3, T4> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#if __TBB_VARIADIC_MAX >= 6
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
class indexer_node<T0, T1, T2, T3, T4, T5> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4, T5> > {
private:
static const int N = 6;
public:
typedef std::tuple<T0, T1, T2, T3, T4, T5> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4, T5> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#endif //variadic max 6
#if __TBB_VARIADIC_MAX >= 7
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
class indexer_node<T0, T1, T2, T3, T4, T5, T6> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4, T5, T6> > {
private:
static const int N = 7;
public:
typedef std::tuple<T0, T1, T2, T3, T4, T5, T6> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#endif //variadic max 7
#if __TBB_VARIADIC_MAX >= 8
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
private:
static const int N = 8;
public:
typedef std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#endif //variadic max 8
#if __TBB_VARIADIC_MAX >= 9
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7, T8> : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
private:
static const int N = 9;
public:
typedef std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#endif //variadic max 9
#if __TBB_VARIADIC_MAX >= 10
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
class indexer_node/*default*/ : public unfolded_indexer_node<std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
private:
static const int N = 10;
public:
typedef std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> InputTuple;
typedef tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> output_type;
typedef unfolded_indexer_node<InputTuple> unfolded_type;
__TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
template <typename... Args>
indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
make_edges_in_order(nodes, *this);
}
#endif
// Copy constructor
__TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) {
fgt_multiinput_node<N>( CODEPTR(), FLOW_INDEXER_NODE, &this->my_graph,
this->input_ports(), static_cast< sender< output_type > *>(this) );
}
};
#endif //variadic max 10
}; // class indexer_node
template< typename T >
inline void internal_make_edge( sender<T> &p, receiver<T> &s ) {
@@ -161,3 +161,83 @@ TEST_CASE("indexer_node copy constructor"){
TEST_CASE("indexer_node output_type") {
CHECK_MESSAGE((conformance::check_output_type<my_output_type, oneapi::tbb::flow::tagged_msg<size_t, int, float, input_msg>>()), "indexer_node output_type should returns a tagged_msg");
}
#include <unordered_set>
template <std::size_t N, typename... Args>
struct indexer_node_type_generator_impl {
using type = typename indexer_node_type_generator_impl<N - 1, Args..., int>::type;
};
template <typename... Args>
struct indexer_node_type_generator_impl<0, Args...> {
using type = oneapi::tbb::flow::indexer_node<Args...>;
};
// Generates oneapi::tbb::flow::indexer_node<int, int, ..., int> with N integer template arguments
template <std::size_t N>
using indexer_node_type_generator_t = typename indexer_node_type_generator_impl<N>::type;
template <std::size_t N>
struct edge_maker {
template <typename SendersVector, typename IndexerNodeType>
static void make(SendersVector& senders, IndexerNodeType& indexer) {
oneapi::tbb::flow::make_edge(senders[N - 1], oneapi::tbb::flow::input_port<N - 1>(indexer));
edge_maker<N - 1>::make(senders, indexer);
}
};
template <>
struct edge_maker<1> {
template <typename SendersVector, typename IndexerNodeType>
static void make(SendersVector& senders, IndexerNodeType& indexer) {
oneapi::tbb::flow::make_edge(senders[0], oneapi::tbb::flow::input_port<0>(indexer));
}
};
template <std::size_t NInputs>
void test_indexer_node_with_n_inputs() {
using namespace oneapi::tbb::flow;
graph g;
int message = 42;
using submitter_type = function_node<int, int>;
std::vector<submitter_type> submitters;
submitters.reserve(NInputs);
for (std::size_t i = 0; i < NInputs; ++i) {
submitters.emplace_back(g, unlimited, [](int obj) { return obj; });
}
using indexer_type = indexer_node_type_generator_t<NInputs>;
indexer_type indexer(g);
edge_maker<NInputs>::make(submitters, indexer);
using output_type = typename indexer_type::output_type;
std::unordered_set<std::size_t> indices;
indices.reserve(NInputs);
function_node<output_type> receiver(g, serial, [&](const output_type& indexer_output) {
indices.emplace(indexer_output.tag());
CHECK_MESSAGE(cast_to<int>(indexer_output) == message, "invalid message returned from indexer_node");
});
make_edge(indexer, receiver);
for (auto& submitter : submitters) {
submitter.try_put(message);
}
g.wait_for_all();
CHECK_MESSAGE(indices.size() == NInputs, "Message from some port lost");
for (std::size_t i = 0; i < NInputs; ++i) {
CHECK(indices.find(i) != indices.end());
}
}
TEST_CASE("indexer_node with large number of inputs") {
test_indexer_node_with_n_inputs<50>();
}