@@ -21,6 +21,11 @@ namespace esimd_test {
21
21
namespace api {
22
22
namespace functional {
23
23
24
+ // Integer pack to store provided int values
25
+ template <int ... T> struct values_pack {
26
+ values_pack () {}
27
+ };
28
+
24
29
// Type pack to store types and underlying data type names to use with
25
30
// type_name_string
26
31
template <typename ... T> struct named_type_pack {
@@ -86,28 +91,56 @@ template <tested_types required> auto get_tested_types() {
86
91
}
87
92
}
88
93
94
+ // Factory method to retrieve pre-defined values_pack, to have the same
95
+ // default dimensions over the tests
96
+ auto get_all_dimensions () { return values_pack<1 , 8 , 16 , 32 >(); }
97
+
89
98
// Run action for each of types given by named_type_pack instance
90
- template <template <typename , typename ...> class action ,
91
- typename ... actionArgsT, typename ... types, typename ... argsT>
92
- inline bool for_all_types (const named_type_pack<types...> &typeList,
93
- argsT &&... args) {
99
+ template <template <typename , int , typename ...> class Action , int N,
100
+ typename ... ActionArgsT, typename ... Types, typename ... ArgsT>
101
+ inline bool for_all_types (const named_type_pack<Types...> &type_list,
102
+ ArgsT &&... args) {
103
+ bool passed{true };
104
+
105
+ size_t type_name_index = 0 ;
106
+
107
+ // Run action for each type from named_type_pack... parameter pack
108
+ ((passed &= Action<Types, N, ActionArgsT...>{}(
109
+ std::forward<ArgsT>(args)..., type_list.names [type_name_index]),
110
+ ++type_name_index),
111
+ ...);
112
+ // The unary right fold expression is used for parameter pack expansion.
113
+ // Every expression with comma operator is strictly sequenced, so we can
114
+ // increment safely. And of course the fold expression would not be optimized
115
+ // out due to side-effects.
116
+ // Additional pair of brackets is required because of precedence of increment
117
+ // operator relative to the comma operator.
118
+ //
119
+ // Note that there is actually no difference in left or right fold expression
120
+ // for the comma operator, as it would give the same order of actions
121
+ // execution and the same order of the type name index increment: both the
122
+ // "(expr0, (exr1, expr2))" and "((expr0, expr1), expr2)" would give the same
123
+ // result as simple "expr0, expr1, expr2"
124
+
125
+ return passed;
126
+ }
127
+
128
+ // Calls for_all_types for each vector length by values_pack instance
129
+ template <template <typename , int , typename ...> class Action ,
130
+ typename ... ActionArgsT, typename ... Types, int ... Dims,
131
+ typename ... ArgsT>
132
+ inline bool for_all_types_and_dims (const named_type_pack<Types...> &type_list,
133
+ const values_pack<Dims...> &dim_list,
134
+ ArgsT &&... args) {
94
135
bool passed{true };
95
136
96
- // run action for each type from types... parameter pack
97
- size_t typeNameIndex = 0 ;
98
-
99
- int packExpansion[] = {
100
- (passed &= action<types, actionArgsT...>{}(std::forward<argsT>(args)...,
101
- typeList.names [typeNameIndex]),
102
- ++typeNameIndex,
103
- 0 // Dummy initialization value
104
- )...};
105
- // Every initializer clause is sequenced before any initializer clause that
106
- // follows it in the braced-init-list. Every expression in comma operator is
107
- // also strictly sequenced. So we can use increment safely. We still should
108
- // discard dummy results, but this initialization should not be optimized out
109
- // due side-effects
110
- static_cast <void >(packExpansion);
137
+ // Run action for each value from values_pack... parameter pack
138
+ ((passed &= for_all_types<Action, Dims, ActionArgsT...>(
139
+ type_list, std::forward<ArgsT>(args)...)),
140
+ ...);
141
+ // The unary right fold expression is used for parameter pack expansion.
142
+ // An additional pair of brackets is required because of precedence of any
143
+ // operator relatively to the comma operator.
111
144
112
145
return passed;
113
146
}
0 commit comments