@@ -68,6 +68,32 @@ struct ForEachType<Functor>
6868
6969namespace internal
7070{
71+ /*
72+ * Apply types contained in Tuple to the template Templ.
73+ */
74+ template <template <typename ...> typename Templ, typename Tuple>
75+ struct apply_tuple_types ;
76+ template <template <typename ...> typename Templ, typename ... Args>
77+ struct apply_tuple_types <Templ, std::tuple<Args...>>
78+ {
79+ using type = Templ<Args...>;
80+ };
81+ template <template <typename ...> typename Templ, typename Tuple>
82+ using apply_tuple_types_t = typename apply_tuple_types<Templ, Tuple>::type;
83+
84+ /*
85+ * Add a first type before the others in Tuple.
86+ */
87+ template <typename FirstType, typename Tuple>
88+ struct prepend_to_tuple ;
89+ template <typename FirstType, typename ... Othertypes>
90+ struct prepend_to_tuple <FirstType, std::tuple<Othertypes...>>
91+ {
92+ using type = std::tuple<FirstType, Othertypes...>;
93+ };
94+ template <typename FirstType, typename Tuple>
95+ using prepend_to_tuple_t =
96+ typename prepend_to_tuple<FirstType, Tuple>::type;
7197
7298 template <typename Functor, typename ... Tuples>
7399 struct ForEachTypeNestedImpl ;
@@ -77,30 +103,10 @@ namespace internal
77103 struct ForEachTypeNestedImpl <Functor, FirstTuple, Tuples...>
78104 {
79105
80- template <typename InnerFunctor, typename Tuple>
81- struct ForEachType_Tuple ;
82-
83- template <typename InnerFunctor, typename ... Types>
84- struct ForEachType_Tuple <InnerFunctor, std::tuple<Types...>>
85- {
86- template <typename ... Args>
87- static void call (Args &&...args)
88- {
89- ForEachType<InnerFunctor, Types...>::template call<Args...>(
90- std::forward<Args>(args)...);
91- }
92- };
93-
94- template <typename FirstType, typename Tuple>
95- struct PrependToTuple ;
96- template <typename FirstType, typename ... Othertypes>
97- struct PrependToTuple <FirstType, std::tuple<Othertypes...>>
98- {
99- using type = std::tuple<FirstType, Othertypes...>;
100- };
101-
102- // transform the outer Functor such that the first type argument
103- // FirstType is already specified
106+ /*
107+ * Transform the outer Functor such that the first type argument
108+ * FirstType is already specified
109+ */
104110 template <typename FirstType>
105111 struct PartialApply
106112 {
@@ -110,12 +116,16 @@ namespace internal
110116 static void call (Args &&...args)
111117 {
112118 using concatenated_tuple_t =
113- typename PrependToTuple <FirstType, RestTypes>::type ;
119+ prepend_to_tuple_t <FirstType, RestTypes>;
114120 Functor::template call<concatenated_tuple_t , Args...>(
115121 std::forward<Args>(args)...);
116122 }
117123 };
118124
125+ /*
126+ * Internal Functor to be passed to ForEachType, for iterating every
127+ * type contained in FirstTuple.
128+ */
119129 struct Runner
120130 {
121131 template <typename Type1, typename ... Args>
@@ -131,8 +141,10 @@ namespace internal
131141 template <typename ... Args>
132142 static void call (Args &&...args)
133143 {
134- // outer loop
135- using foreach_t = ForEachType_Tuple<Runner, FirstTuple>;
144+ // outer loop --> iterate over each type contained in FirstTuple
145+ using foreach_t = apply_tuple_types_t <
146+ ForEachType,
147+ prepend_to_tuple_t <Runner, FirstTuple>>;
136148 foreach_t ::template call<Args...>(std::forward<Args>(args)...);
137149 }
138150 };
@@ -149,6 +161,23 @@ namespace internal
149161 };
150162} // namespace internal
151163
164+ /*
165+ * Functor is a struct of the form:
166+ *
167+ * struct Functor
168+ * {
169+ * template<typename T1, typename T2, ...>
170+ * static void call(... any kind of argument ...);
171+ * };
172+ *
173+ * The variadic parameter pack (Tuples) specifies for each template parameter
174+ * (T1, T2, ...) of the call<>() function template a tuple of types that should
175+ * be applied.
176+ *
177+ * ForEachTypeNested<Functor, Tuple1, Tuple2, ...>::call(...args...) will then
178+ * call Functor::template call<T1, T2, ...>() for each possible combination of
179+ * T1 <- Tuple1, T2 <- Tuple2, ...
180+ */
152181template <typename Functor, typename ... Tuples>
153182struct ForEachTypeNested
154183{
@@ -165,6 +194,15 @@ struct ForEachTypeNested
165194 }
166195 };
167196
197+ /*
198+ * For easier internal handling, transform the Functor into one that
199+ * accepts its template parameters as a single Tuple argument of the form
200+ * std::tuple<T1, T2, ...>.
201+ * This is necessary since we need variadic arguments already
202+ * to generically specify that the call function template accepts any kinds
203+ * of arguments; and we cannot have more than one range of variadic type
204+ * args.
205+ */
168206 struct TupledFunctor
169207 {
170208 template <typename Tuple, typename ... Args>
0 commit comments