OGS
Apply.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include "Get.h"
7
9{
10namespace detail
11{
12template <typename Function>
15 : GetFunctionArgumentTypes<decltype(&Function::operator())>
17{
18};
19
20// member function
21template <typename Result, typename Class, typename... Args>
22struct GetFunctionArgumentTypes<Result (Class::*)(Args...)>
23{
24 using type = boost::mp11::mp_list<Args...>;
25};
26
27// const member function
28template <typename Result, typename Class, typename... Args>
29struct GetFunctionArgumentTypes<Result (Class::*)(Args...) const>
30{
31 using type = boost::mp11::mp_list<Args...>;
32};
33
34// standalone function
35template <typename Result, typename... Args>
36struct GetFunctionArgumentTypes<Result (*)(Args...)>
37{
38 using type = boost::mp11::mp_list<Args...>;
39};
40
41// plain, i.e., without cvref
42template <typename Function>
44 std::type_identity<boost::mp11::mp_transform<
45 std::remove_cvref_t,
47
48template <typename Function>
51 : GetFunctionReturnType<decltype(&Function::operator())>
53{
54};
55
56// member function
57template <typename Result, typename Class, typename... Args>
58struct GetFunctionReturnType<Result (Class::*)(Args...)>
59{
60 using type = Result;
61};
62
63// const member function
64template <typename Result, typename Class, typename... Args>
65struct GetFunctionReturnType<Result (Class::*)(Args...) const>
66{
67 using type = Result;
68};
69
70// standalone function
71template <typename Result, typename... Args>
72struct GetFunctionReturnType<Result (*)(Args...)>
73{
74 using type = Result;
75};
76
77// Invokes the passed function object with arguments taken ("unpacked") from the
78// passed tuples ts. The arguments are picked/passed according to their data
79// type.
80//
81// overload for function objects
82template <typename Object,
83 typename... Tuples,
84 typename... MemberFunctionArgumentTypesPlain>
85auto unpackAndInvoke(boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...>,
86 Object&& o,
87 Tuples&... ts) ->
88 // std::decay_t "decays" lambdas
89 typename GetFunctionReturnType<
90 decltype(&std::decay_t<Object>::operator())>::type
91{
92 return o(
94}
95
96// member function
97template <typename Result,
98 typename Object,
99 typename... Args,
100 typename... Tuples,
101 typename... MemberFunctionArgumentTypesPlain>
103 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...>,
104 Result (Object::*m)(Args...),
105 Object& o,
106 Tuples&... ts)
107{
108 return (o.*m)(
110}
111
112// member function & temporary object
113template <typename Result,
114 typename Object,
115 typename... Args,
116 typename... Tuples,
117 typename... MemberFunctionArgumentTypesPlain>
119 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...>,
120 Result (Object::*m)(Args...),
121 Object&& o,
122 Tuples&... ts)
123{
124 return (o.*m)(
126}
127
128// const member function
129template <typename Result,
130 typename Object,
131 typename... Args,
132 typename... Tuples,
133 typename... MemberFunctionArgumentTypesPlain>
135 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...>,
136 Result (Object::*m)(Args...) const,
137 Object const& o,
138 Tuples&... ts)
139{
140 return (o.*m)(
142}
143
144// standalone function
145template <typename Result,
146 typename... Args,
147 typename... Tuples,
148 typename... FunctionArgumentTypesPlain>
149Result unpackAndInvoke(boost::mp11::mp_list<FunctionArgumentTypesPlain...>,
150 Result (*fct)(Args...),
151 Tuples&... ts)
152{
154}
155
156template <typename Function, typename... PassedArgsTuples>
159 : GetFlattenedTupleOfPassedArgs<decltype(&Function::operator()),
160 Function,
161 PassedArgsTuples...>
163{
164};
165
166// member function
167template <typename Result,
168 typename Class,
169 typename... DeclaredArgs,
170 typename ClassAgain,
171 typename... PassedArgsTuples>
172struct GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...),
173 // first "argument" is the object to which
174 // the member function belongs
175 ClassAgain,
176 PassedArgsTuples...>
177{
179 std::remove_cvref_t<PassedArgsTuples>...>::type;
180};
181
182// const member function
183template <typename Result,
184 typename Class,
185 typename... DeclaredArgs,
186 typename... ClassAndPassedArgsTuples>
187struct GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...) const,
188 ClassAndPassedArgsTuples...>
189 // redirect to non-const member function implementation
190 : GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...),
191 ClassAndPassedArgsTuples...>
192{
193};
194
195// standalone function
196template <typename Result, typename... DeclaredArgs, typename... Tuples>
197struct GetFlattenedTupleOfPassedArgs<Result (*)(DeclaredArgs...), Tuples...>
198{
200 std::remove_cvref_t<Tuples>...>::type;
201};
202
213template <typename Function, typename... Args>
214auto applyImpl(Function&& f, Args&&... args) ->
216{
217 using namespace boost::mp11;
218
219 using FunctionPlain = std::decay_t<Function>;
220 using FlattenedTuple =
221 typename GetFlattenedTupleOfPassedArgs<FunctionPlain, Args...>::type;
222 using FlattenedTupleOfPlainTypes =
223 mp_transform<std::remove_cvref_t, FlattenedTuple>;
224
225 static_assert(
227 "The types of all elements of all passed tuples must be unique.");
228
229 using FunctionArgumentTypesPlain =
231
232 static_assert(
234 "The argument types of the function to be called must be unique.");
235
236 return unpackAndInvoke(FunctionArgumentTypesPlain{},
237 std::forward<Function>(f),
238 std::forward<Args>(args)...);
239}
240} // namespace detail
241
250template <typename Function, typename... Tuples>
251auto apply(Function& f, Tuples&... ts) ->
253{
254 static_assert(boost::mp11::mp_similar<std::tuple<>,
255 std::remove_cv_t<Tuples>...>::value,
256 "In the argument ts... there must be only std::tuple's.");
257
258 return detail::applyImpl(f, ts...);
259}
260
267template <typename Function, typename... Tuples>
268auto eval(Function& f, Tuples&... ts) ->
269 typename detail::GetFunctionReturnType<decltype(&Function::eval)>::type
270{
271 static_assert(boost::mp11::mp_similar<std::tuple<>,
272 std::remove_cv_t<Tuples>...>::value,
273 "In the argument ts... there must be only std::tuple's.");
274
275 return detail::applyImpl(&Function::eval, f, ts...);
276}
277
287template <typename Functions, typename... Tuples>
288void evalAllInOrder(Functions& fs, Tuples&... ts)
289{
290 boost::mp11::tuple_for_each(fs, [&ts...](auto& f) { eval(f, ts...); });
291}
292} // namespace ProcessLib::Graph
auto unpackAndInvoke(boost::mp11::mp_list< MemberFunctionArgumentTypesPlain... >, Object &&o, Tuples &... ts) -> typename GetFunctionReturnType< decltype(&std::decay_t< Object >::operator())>::type
Definition Apply.h:85
auto applyImpl(Function &&f, Args &&... args) -> typename detail::GetFunctionReturnType< std::decay_t< Function > >::type
Definition Apply.h:214
std::type_identity< boost::mp11::mp_transform< std::remove_cvref_t, typename GetFunctionArgumentTypes< Function >::type > > GetFunctionArgumentTypesPlain
Definition Apply.h:43
auto apply(Function &f, Tuples &... ts) -> typename detail::GetFunctionReturnType< std::decay_t< Function > >::type
Definition Apply.h:251
auto & get(Tuples &... ts)
Definition Get.h:53
void evalAllInOrder(Functions &fs, Tuples &... ts)
Definition Apply.h:288
auto eval(Function &f, Tuples &... ts) -> typename detail::GetFunctionReturnType< decltype(&Function::eval)>::type
Definition Apply.h:268
constexpr bool mp_is_set_v
typename detail::GetFlattenedTupleTypes< std::remove_cvref_t< PassedArgsTuples >... >::type type
Definition Apply.h:178
typename detail::GetFlattenedTupleTypes< std::remove_cvref_t< Tuples >... >::type type
Definition Apply.h:199