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>
86 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...> /*unused*/,
87 Object&& o,
88 Tuples&... ts) ->
89 // std::decay_t "decays" lambdas
90 typename GetFunctionReturnType<
91 decltype(&std::decay_t<Object>::operator())>::type
92{
93 return o(
95}
96
97// member function
98template <typename Result,
99 typename Object,
100 typename... Args,
101 typename... Tuples,
102 typename... MemberFunctionArgumentTypesPlain>
104 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...> /*unused*/,
105 Result (Object::*m)(Args...),
106 Object& o,
107 Tuples&... ts)
108{
109 return (o.*m)(
111}
112
113// member function & temporary object
114template <typename Result,
115 typename Object,
116 typename... Args,
117 typename... Tuples,
118 typename... MemberFunctionArgumentTypesPlain>
120 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...> /*unused*/,
121 Result (Object::*m)(Args...),
122 Object&& o,
123 Tuples&... ts)
124{
125 return (o.*m)(
127}
128
129// const member function
130template <typename Result,
131 typename Object,
132 typename... Args,
133 typename... Tuples,
134 typename... MemberFunctionArgumentTypesPlain>
136 boost::mp11::mp_list<MemberFunctionArgumentTypesPlain...> /*unused*/,
137 Result (Object::*m)(Args...) const,
138 Object const& o,
139 Tuples&... ts)
140{
141 return (o.*m)(
143}
144
145// standalone function
146template <typename Result,
147 typename... Args,
148 typename... Tuples,
149 typename... FunctionArgumentTypesPlain>
151 boost::mp11::mp_list<FunctionArgumentTypesPlain...> /*unused*/,
152 Result (*fct)(Args...),
153 Tuples&... ts)
154{
156}
157
158template <typename Function, typename... PassedArgsTuples>
161 : GetFlattenedTupleOfPassedArgs<decltype(&Function::operator()),
162 Function,
163 PassedArgsTuples...>
165{
166};
167
168// member function
169template <typename Result,
170 typename Class,
171 typename... DeclaredArgs,
172 typename ClassAgain,
173 typename... PassedArgsTuples>
174struct GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...),
175 // first "argument" is the object to which
176 // the member function belongs
177 ClassAgain,
178 PassedArgsTuples...>
179{
181 std::remove_cvref_t<PassedArgsTuples>...>::type;
182};
183
184// const member function
185template <typename Result,
186 typename Class,
187 typename... DeclaredArgs,
188 typename... ClassAndPassedArgsTuples>
189struct GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...) const,
190 ClassAndPassedArgsTuples...>
191 // redirect to non-const member function implementation
192 : GetFlattenedTupleOfPassedArgs<Result (Class::*)(DeclaredArgs...),
193 ClassAndPassedArgsTuples...>
194{
195};
196
197// standalone function
198template <typename Result, typename... DeclaredArgs, typename... Tuples>
199struct GetFlattenedTupleOfPassedArgs<Result (*)(DeclaredArgs...), Tuples...>
200{
202 std::remove_cvref_t<Tuples>...>::type;
203};
204
215template <typename Function, typename... Args>
216auto applyImpl(Function&& f, Args&&... args) ->
218{
219 using namespace boost::mp11;
220
221 using FunctionPlain = std::decay_t<Function>;
222 using FlattenedTuple =
223 typename GetFlattenedTupleOfPassedArgs<FunctionPlain, Args...>::type;
224 using FlattenedTupleOfPlainTypes =
225 mp_transform<std::remove_cvref_t, FlattenedTuple>;
226
227 static_assert(
229 "The types of all elements of all passed tuples must be unique.");
230
231 using FunctionArgumentTypesPlain =
233
234 static_assert(
236 "The argument types of the function to be called must be unique.");
237
238 return unpackAndInvoke(FunctionArgumentTypesPlain{},
239 std::forward<Function>(f),
240 std::forward<Args>(args)...);
241}
242} // namespace detail
243
252template <typename Function, typename... Tuples>
253auto apply(Function& f, Tuples&... ts) ->
255{
256 static_assert(boost::mp11::mp_similar<std::tuple<>,
257 std::remove_cv_t<Tuples>...>::value,
258 "In the argument ts... there must be only std::tuple's.");
259
260 return detail::applyImpl(f, ts...);
261}
262
269template <typename Function, typename... Tuples>
270auto eval(Function& f, Tuples&... ts) ->
271 typename detail::GetFunctionReturnType<decltype(&Function::eval)>::type
272{
273 static_assert(boost::mp11::mp_similar<std::tuple<>,
274 std::remove_cv_t<Tuples>...>::value,
275 "In the argument ts... there must be only std::tuple's.");
276
277 return detail::applyImpl(&Function::eval, f, ts...);
278}
279
289template <typename Functions, typename... Tuples>
290void evalAllInOrder(Functions& fs, Tuples&... ts)
291{
292 boost::mp11::tuple_for_each(fs, [&ts...](auto& f) { eval(f, ts...); });
293}
294} // 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:216
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:253
auto & get(Tuples &... ts)
Definition Get.h:53
void evalAllInOrder(Functions &fs, Tuples &... ts)
Definition Apply.h:290
auto eval(Function &f, Tuples &... ts) -> typename detail::GetFunctionReturnType< decltype(&Function::eval)>::type
Definition Apply.h:270
constexpr bool mp_is_set_v
typename detail::GetFlattenedTupleTypes< std::remove_cvref_t< PassedArgsTuples >... >::type type
Definition Apply.h:180
typename detail::GetFlattenedTupleTypes< std::remove_cvref_t< Tuples >... >::type type
Definition Apply.h:201