dune-functions 2.9.0
utility.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_FUNCTIONS_COMMON_UTILITY_HH
4#define DUNE_FUNCTIONS_COMMON_UTILITY_HH
5
6
7#include <utility>
8#include <type_traits>
9
10#include <dune/common/overloadset.hh>
11#include <dune/common/indices.hh>
12
14
15namespace Dune {
16namespace Functions {
17
18
19
20template<class F, class size_type, size_type firstValue, class... Args>
21auto forwardAsStaticInteger(std::integer_sequence<size_type, firstValue> values, const size_type& i, F&& f, Args&&... args)
22 ->decltype(f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...))
23{
24 return f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...);
25}
26
27template<class F, class size_type, size_type firstValue, size_type secondValue, size_type... otherValues, class... Args>
28auto forwardAsStaticInteger(std::integer_sequence<size_type, firstValue, secondValue, otherValues...> values, const size_type i, F&& f, Args&&... args)
29 ->decltype(f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...))
30{
31 if (i==firstValue)
32 return f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...);
33 return forwardAsStaticInteger(std::integer_sequence<size_type, secondValue, otherValues...>(), i, std::forward<F>(f), std::forward<Args>(args)...);
34}
35
36
37
59template<std::size_t end, class F, class size_type, class... Args>
60auto forwardAsStaticIndex(const size_type& i, F&& f, Args&&... args)
61 ->decltype(f(Dune::Indices::_0, std::forward<Args>(args)...))
62{
63 return forwardAsStaticInteger(std::make_index_sequence<end>{}, i, std::forward<F>(f), std::forward<Args>(args)...);
64}
65
66
67
68namespace Imp {
69
70 template<template<class...> class T, class List>
71 struct ExpandTupleHelper
72 {};
73
74 template<template<class...> class T, template<class...> class ListType, class... Args>
75 struct ExpandTupleHelper<T, ListType<Args...>>
76 {
77 using Type = T<Args...>;
78 };
79
80} // end namespace Imp
81
93template<template<class...> class T, class ArgTuple>
94using ExpandTuple = typename Imp::ExpandTupleHelper<T, ArgTuple>::Type;
95
96
97
98namespace Imp {
99
100 template<template<class...> class T, class... Tuple>
101 struct TransformTupleHelper
102 {};
103
104 template<template<class...> class T, class... Args1>
105 struct TransformTupleHelper<T, typename std::tuple<Args1...>>
106 {
107 using Type = std::tuple<T<Args1>...>;
108 };
109
110 template<template<class...> class T, class... Args1, class... Args2>
111 struct TransformTupleHelper<T, typename std::tuple<Args1...>, typename std::tuple<Args2...>>
112 {
113 using Type = std::tuple<T<Args1, Args2>...>;
114 };
115
116} // end namespace Imp
117
130template<template<class...> class F, class... Tuples>
131using TransformTuple = typename Imp::TransformTupleHelper<F, Tuples...>::Type;
132
133
134
135namespace Imp {
136
137 template<class F, class... T, std::size_t... k>
138 auto transformTupleHelper(F&& f, const std::tuple<T...>& tuple, std::index_sequence<k...>)
139 -> decltype(std::make_tuple(f(std::get<k>(tuple))...))
140 {
141 return std::make_tuple(f(std::get<k>(tuple))...);
142 }
143
144 template<class F, class... T1, class...T2, std::size_t... k>
145 auto transformTupleHelper(F&& f, const std::tuple<T1...>& tuple1, const std::tuple<T2...>& tuple2, std::index_sequence<k...>)
146 -> decltype(std::make_tuple(f(std::get<k>(tuple1), std::get<k>(tuple2))...))
147 {
148 return std::make_tuple(f(std::get<k>(tuple1), std::get<k>(tuple2))...);
149 }
150
151} // end namespace Imp
152
164template<class F, class... T>
165auto transformTuple(F&& f, const std::tuple<T...>& tuple)
166 -> decltype(Imp::transformTupleHelper(std::forward<F>(f), tuple, std::index_sequence_for<T...>{}))
167{
168 return Imp::transformTupleHelper(std::forward<F>(f), tuple, std::index_sequence_for<T...>{});
169}
170
184template<class F, class... T1, class... T2>
185auto transformTuple(F&& f, const std::tuple<T1...>& tuple1, const std::tuple<T2...>& tuple2)
186 -> decltype(Imp::transformTupleHelper(std::forward<F>(f), tuple1, tuple2, std::index_sequence_for<T1...>{}))
187{
188 return Imp::transformTupleHelper(std::forward<F>(f), tuple1, tuple2, std::index_sequence_for<T1...>{});
189}
190
191
192
193namespace Imp {
194
195 template<class IntegerSequence>
196 struct IntegerSequenceTupleHelper
197 {};
198
199 template<class I, I... k>
200 struct IntegerSequenceTupleHelper<std::integer_sequence<I, k...>>
201 {
202 using Type = std::tuple<std::integral_constant<I, k>...>;
203 };
204
205} // end namespace Imp
206
210template<class IntegerSequence>
211using IntegerSequenceTuple= typename Imp::IntegerSequenceTupleHelper<IntegerSequence>::Type;
212
213
214
220template<class... T>
222{
223 using type = typename std::tuple_element<sizeof...(T)-1, std::tuple<T...>>::type;
224};
225
226
227
228namespace Imp {
229
230template<class T, class I>
231struct RotateHelper;
232
233template<class... T, std::size_t... I>
234struct RotateHelper<std::tuple<T...>, std::index_sequence<I...> >
235{
236 using type = typename std::tuple<typename LastType<T...>::type, typename std::tuple_element<I,std::tuple<T...>>::type...>;
237};
238
239} // end namespace Imp
240
241
249template<class... T>
251{
252 using type = typename Imp::RotateHelper<std::tuple<T...>, std::make_index_sequence<sizeof...(T)-1>>::type;
253};
254
255
256
278template<class Expression>
279auto callableCheck(Expression f)
280{
281 return [f](auto&&... args){
282 return Functions::Concept::isCallable(f, std::forward<decltype(args)>(args)...);
283 };
284}
285
286
287
303template<class Check>
304auto negatePredicate(Check check)
305{
306 return [check](auto&&... args){
307 auto negate = overload(
308 [](std::true_type) { return std::false_type{};},
309 [](std::false_type) { return std::true_type{};},
310 [](bool v) { return not v;});
311 return negate(check(std::forward<decltype(args)>(args)...));
312 };
313}
314
315
316namespace Impl {
317
318 // Wrapper to capture values in a lambda for perfect forwarding.
319 // This captures value types by value and reference types by reference.
320 template <typename T>
321 struct ForwardCaptureWrapper;
322
323 template <typename T>
324 struct ForwardCaptureWrapper
325 {
326 template <typename TT>
327 ForwardCaptureWrapper(TT&& t) : t_{std::forward<TT>(t)} {}
328
329 auto forward() const { return std::move(t_); }
330
331 T t_;
332 };
333
334 template <typename T>
335 struct ForwardCaptureWrapper<T&>
336 {
337 ForwardCaptureWrapper(T& t) : t_{t} {}
338
339 T& forward() const { return t_; };
340
341 T& t_;
342 };
343
344 template <typename T>
345 struct ForwardCaptureWrapper<const T&>
346 {
347 ForwardCaptureWrapper(const T& t) : t_{t} {}
348
349 const T& forward() const { return t_; };
350
351 const T& t_;
352 };
353
354} // end namespace Dune::Functions::Impl
355
356
357
371template <class T>
372auto forwardCapture(T&& t)
373{
374 return Impl::ForwardCaptureWrapper<T>(std::forward<T>(t));
375}
376
377
378
379} // namespace Dune::Functions
380} // namespace Dune
381
382
383#endif // DUNE_FUNCTIONS_COMMON_UTILITY_HH
typename Imp::ExpandTupleHelper< T, ArgTuple >::Type ExpandTuple
Expand tuple arguments as template arguments.
Definition: utility.hh:94
typename Imp::TransformTupleHelper< F, Tuples... >::Type TransformTuple
Transform tuple types argument using type-functor.
Definition: utility.hh:131
static constexpr auto isCallable()
Check if f is callable with given argument list.
Definition: functionconcepts.hh:47
auto transformTuple(F &&f, const std::tuple< T... > &tuple) -> decltype(Imp::transformTupleHelper(std::forward< F >(f), tuple, std::index_sequence_for< T... >{}))
Transform tuple value using a functor.
Definition: utility.hh:165
auto callableCheck(Expression f)
Create a predicate for checking validity of expressions.
Definition: utility.hh:279
auto forwardAsStaticIndex(const size_type &i, F &&f, Args &&... args) -> decltype(f(Dune::Indices::_0, std::forward< Args >(args)...))
Transform dynamic index to static index_constant.
Definition: utility.hh:60
auto negatePredicate(Check check)
Negate given predicate.
Definition: utility.hh:304
Definition: polynomial.hh:10
auto forwardCapture(T &&t)
Create a capture object for perfect forwarding.
Definition: utility.hh:372
auto forwardAsStaticInteger(std::integer_sequence< size_type, firstValue > values, const size_type &i, F &&f, Args &&... args) -> decltype(f(std::integral_constant< size_type, firstValue >(), std::forward< Args >(args)...))
Definition: utility.hh:21
typename Imp::IntegerSequenceTupleHelper< IntegerSequence >::Type IntegerSequenceTuple
Transform integer_sequence<I,k...> to tuple<integral_constant<I,k>...>
Definition: utility.hh:211
Get last entry of type list.
Definition: utility.hh:222
typename std::tuple_element< sizeof...(T) -1, std::tuple< T... > >::type type
Definition: utility.hh:223
Rotate type list by one, such that last entry is moved to first position.
Definition: utility.hh:251
typename Imp::RotateHelper< std::tuple< T... >, std::make_index_sequence< sizeof...(T) -1 > >::type type
Definition: utility.hh:252