Skip to content

Commit 134dc89

Browse files
committed
Add untested ForEachTypeNested
1 parent 82b600b commit 134dc89

1 file changed

Lines changed: 119 additions & 1 deletion

File tree

include/openPMD/binding/python/auxiliary.hpp

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ struct ForEachType<Functor, FirstType, OtherTypes...>
3737
static void call(Args &&...args)
3838
{
3939
Functor::template call<FirstType>(args...);
40-
ForEachType<Functor, OtherTypes...>::template call<Args...>(args...);
40+
ForEachType<Functor, OtherTypes...>::template call<Args...>(
41+
std::forward<Args>(args)...);
4142
}
4243
};
4344

@@ -49,4 +50,121 @@ struct ForEachType<Functor>
4950
{ /* no-op */
5051
}
5152
};
53+
54+
namespace internal
55+
{
56+
57+
template <typename Functor, typename... Tuples>
58+
struct ForEachTypeNestedImpl;
59+
60+
// Functor::template call<std::tuple<Type1, Type2, Type3, ...>>(args...)
61+
template <typename Functor, typename FirstTuple, typename... Tuples>
62+
struct ForEachTypeNestedImpl<Functor, FirstTuple, Tuples...>
63+
{
64+
65+
template <typename InnerFunctor, typename Tuple>
66+
struct ForEachType_Tuple;
67+
68+
template <typename InnerFunctor, typename... Types>
69+
struct ForEachType_Tuple<InnerFunctor, std::tuple<Types...>>
70+
{
71+
template <typename... Args>
72+
static void call(Args &&...args)
73+
{
74+
ForEachType<InnerFunctor, Types...>::template call<Args...>(
75+
std::forward<Args>(args)...);
76+
}
77+
};
78+
79+
template <typename FirstType, typename Tuple>
80+
struct PrependToTuple;
81+
template <typename FirstType, typename... Othertypes>
82+
struct PrependToTuple<FirstType, std::tuple<Othertypes...>>
83+
{
84+
using type = std::tuple<FirstType, Othertypes...>;
85+
};
86+
87+
// transform the outer Functor such that the first type argument
88+
// FirstType is already specified
89+
template <typename FirstType>
90+
struct PartialApply
91+
{
92+
// RestType is a tuple
93+
// Args the function arguments
94+
template <typename RestTypes, typename... Args>
95+
static void call(Args &&...args)
96+
{
97+
using concatenated_tuple_t =
98+
typename PrependToTuple<FirstType, RestTypes>::type;
99+
Functor::template call<concatenated_tuple_t, Args...>(
100+
std::forward<Args>(args)...);
101+
}
102+
};
103+
104+
struct Runner
105+
{
106+
template <typename Type1, typename... Args>
107+
static void call(Args &&...args)
108+
{
109+
using partially_applied_t = PartialApply<Type1>;
110+
// recursive call
111+
ForEachTypeNestedImpl<partially_applied_t, Tuples...>::
112+
template call<Args...>(std::forward<Args>(args)...);
113+
}
114+
};
115+
116+
template <typename... Args>
117+
static void call(Args &&...args)
118+
{
119+
// outer loop
120+
using foreach_t = ForEachType_Tuple<Runner, FirstTuple>;
121+
foreach_t::template call<Args...>(std::forward<Args>(args)...);
122+
}
123+
};
124+
125+
template <typename Functor>
126+
struct ForEachTypeNestedImpl<Functor>
127+
{
128+
template <typename... Args>
129+
static void call(Args &&...args)
130+
{
131+
Functor::template call<std::tuple<>, Args...>(
132+
std::forward<Args>(args)...);
133+
}
134+
};
135+
} // namespace internal
136+
137+
template <typename Functor, typename... Tuples>
138+
struct ForEachTypeNested
139+
{
140+
template <typename InnerFunctor, typename Tuple>
141+
struct ApplyTupleAsTypes;
142+
143+
template <typename InnerFunctor, typename... Types>
144+
struct ApplyTupleAsTypes<InnerFunctor, std::tuple<Types...>>
145+
{
146+
template <typename... Args>
147+
static void call(Args &&...args)
148+
{
149+
InnerFunctor::template call<Types...>(std::forward<Args>(args)...);
150+
}
151+
};
152+
153+
struct TupledFunctor
154+
{
155+
template <typename Tuple, typename... Args>
156+
static void call(Args &&...args)
157+
{
158+
ApplyTupleAsTypes<Functor, Tuple>::template call<Args...>(
159+
std::forward<Args>(args)...);
160+
}
161+
};
162+
163+
template <typename... Args>
164+
static void call(Args &&...args)
165+
{
166+
internal::ForEachTypeNestedImpl<TupledFunctor, Tuples...>::
167+
template call<Args...>(std::forward<Args>(args)...);
168+
}
169+
};
52170
} // namespace auxiliary

0 commit comments

Comments
 (0)