DUNE-FUNCTIONS (unstable)

utility.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_COMMON_UTILITY_HH
8#define DUNE_FUNCTIONS_COMMON_UTILITY_HH
9
10
11#include <utility>
12#include <type_traits>
13
14#include <dune/common/overloadset.hh>
15#include <dune/common/indices.hh>
16
17#include <dune/functions/common/functionconcepts.hh>
18
19namespace Dune {
20namespace Functions {
21
22
23
24template<class F, class size_type, size_type firstValue, class... Args>
25auto forwardAsStaticInteger(std::integer_sequence<size_type, firstValue> values, const size_type& i, F&& f, Args&&... args)
26 ->decltype(f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...))
27{
28 return f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...);
29}
30
31template<class F, class size_type, size_type firstValue, size_type secondValue, size_type... otherValues, class... Args>
32auto forwardAsStaticInteger(std::integer_sequence<size_type, firstValue, secondValue, otherValues...> values, const size_type i, F&& f, Args&&... args)
33 ->decltype(f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...))
34{
35 if (i==firstValue)
36 return f(std::integral_constant<size_type, firstValue>(), std::forward<Args>(args)...);
37 return forwardAsStaticInteger(std::integer_sequence<size_type, secondValue, otherValues...>(), i, std::forward<F>(f), std::forward<Args>(args)...);
38}
39
40
41
63template<std::size_t end, class F, class size_type, class... Args>
64auto forwardAsStaticIndex(const size_type& i, F&& f, Args&&... args)
65 ->decltype(f(Dune::Indices::_0, std::forward<Args>(args)...))
66{
67 return forwardAsStaticInteger(std::make_index_sequence<end>{}, i, std::forward<F>(f), std::forward<Args>(args)...);
68}
69
70
71
72namespace Imp {
73
74 template<template<class...> class T, class List>
75 struct ExpandTupleHelper
76 {};
77
78 template<template<class...> class T, template<class...> class ListType, class... Args>
79 struct ExpandTupleHelper<T, ListType<Args...>>
80 {
81 using Type = T<Args...>;
82 };
83
84} // end namespace Imp
85
97template<template<class...> class T, class ArgTuple>
98using ExpandTuple = typename Imp::ExpandTupleHelper<T, ArgTuple>::Type;
99
100
101
102namespace Imp {
103
104 template<template<class...> class T, class... Tuple>
105 struct TransformTupleHelper
106 {};
107
108 template<template<class...> class T, class... Args1>
109 struct TransformTupleHelper<T, typename std::tuple<Args1...>>
110 {
111 using Type = std::tuple<T<Args1>...>;
112 };
113
114 template<template<class...> class T, class... Args1, class... Args2>
115 struct TransformTupleHelper<T, typename std::tuple<Args1...>, typename std::tuple<Args2...>>
116 {
117 using Type = std::tuple<T<Args1, Args2>...>;
118 };
119
120} // end namespace Imp
121
134template<template<class...> class F, class... Tuples>
135using TransformTuple = typename Imp::TransformTupleHelper<F, Tuples...>::Type;
136
137
138
139namespace Imp {
140
141 template<class F, class... T, std::size_t... k>
142 auto transformTupleHelper(F&& f, const std::tuple<T...>& tuple, std::index_sequence<k...>)
143 -> decltype(std::make_tuple(f(std::get<k>(tuple))...))
144 {
145 return std::make_tuple(f(std::get<k>(tuple))...);
146 }
147
148 template<class F, class... T1, class...T2, std::size_t... k>
149 auto transformTupleHelper(F&& f, const std::tuple<T1...>& tuple1, const std::tuple<T2...>& tuple2, std::index_sequence<k...>)
150 -> decltype(std::make_tuple(f(std::get<k>(tuple1), std::get<k>(tuple2))...))
151 {
152 return std::make_tuple(f(std::get<k>(tuple1), std::get<k>(tuple2))...);
153 }
154
155} // end namespace Imp
156
168template<class F, class... T>
169auto transformTuple(F&& f, const std::tuple<T...>& tuple)
170 -> decltype(Imp::transformTupleHelper(std::forward<F>(f), tuple, std::index_sequence_for<T...>{}))
171{
172 return Imp::transformTupleHelper(std::forward<F>(f), tuple, std::index_sequence_for<T...>{});
173}
174
188template<class F, class... T1, class... T2>
189auto transformTuple(F&& f, const std::tuple<T1...>& tuple1, const std::tuple<T2...>& tuple2)
190 -> decltype(Imp::transformTupleHelper(std::forward<F>(f), tuple1, tuple2, std::index_sequence_for<T1...>{}))
191{
192 return Imp::transformTupleHelper(std::forward<F>(f), tuple1, tuple2, std::index_sequence_for<T1...>{});
193}
194
195
196
197namespace Imp {
198
199 template<class IntegerSequence>
200 struct IntegerSequenceTupleHelper
201 {};
202
203 template<class I, I... k>
204 struct IntegerSequenceTupleHelper<std::integer_sequence<I, k...>>
205 {
206 using Type = std::tuple<std::integral_constant<I, k>...>;
207 };
208
209} // end namespace Imp
210
214template<class IntegerSequence>
215using IntegerSequenceTuple= typename Imp::IntegerSequenceTupleHelper<IntegerSequence>::Type;
216
217
218
224template<class... T>
226{
227 using type = std::tuple_element_t<sizeof...(T)-1, std::tuple<T...>>;
228};
229
230
231
232namespace Imp {
233
234template<class T, class I>
235struct RotateHelper;
236
237template<class... T, std::size_t... I>
238struct RotateHelper<std::tuple<T...>, std::index_sequence<I...> >
239{
240 using type = typename std::tuple<typename LastType<T...>::type, std::tuple_element_t<I,std::tuple<T...>>...>;
241};
242
243} // end namespace Imp
244
245
253template<class... T>
255{
256 using type = typename Imp::RotateHelper<std::tuple<T...>, std::make_index_sequence<sizeof...(T)-1>>::type;
257};
258
259
260
282template<class Expression>
283auto callableCheck(Expression f)
284{
285 return [f](auto&&... args){
286 return Functions::Concept::isCallable(f, std::forward<decltype(args)>(args)...);
287 };
288}
289
290
291
307template<class Check>
308auto negatePredicate(Check check)
309{
310 return [check](auto&&... args){
311 auto negate = overload(
312 [](std::true_type) { return std::false_type{};},
313 [](std::false_type) { return std::true_type{};},
314 [](bool v) { return not v;});
315 return negate(check(std::forward<decltype(args)>(args)...));
316 };
317}
318
319
320namespace Impl {
321
322 // Wrapper to capture values in a lambda for perfect forwarding.
323 // This captures value types by value and reference types by reference.
324 template <typename T>
325 struct ForwardCaptureWrapper;
326
327 template <typename T>
328 struct ForwardCaptureWrapper
329 {
330 template <typename TT>
331 ForwardCaptureWrapper(TT&& t) : t_{std::forward<TT>(t)} {}
332
333 auto forward() const { return std::move(t_); }
334
335 T t_;
336 };
337
338 template <typename T>
339 struct ForwardCaptureWrapper<T&>
340 {
341 ForwardCaptureWrapper(T& t) : t_{t} {}
342
343 T& forward() const { return t_; };
344
345 T& t_;
346 };
347
348 template <typename T>
349 struct ForwardCaptureWrapper<const T&>
350 {
351 ForwardCaptureWrapper(const T& t) : t_{t} {}
352
353 const T& forward() const { return t_; };
354
355 const T& t_;
356 };
357
358} // end namespace Dune::Functions::Impl
359
360
361
375template <class T>
376auto forwardCapture(T&& t)
377{
378 return Impl::ForwardCaptureWrapper<T>(std::forward<T>(t));
379}
380
381
382
383} // namespace Dune::Functions
384} // namespace Dune
385
386
387#endif // DUNE_FUNCTIONS_COMMON_UTILITY_HH
typename Imp::ExpandTupleHelper< T, ArgTuple >::Type ExpandTuple
Expand tuple arguments as template arguments.
Definition: utility.hh:98
typename Imp::TransformTupleHelper< F, Tuples... >::Type TransformTuple
Transform tuple types argument using type-functor.
Definition: utility.hh:135
static constexpr auto isCallable()
Check if f is callable with given argument list.
Definition: functionconcepts.hh:51
auto callableCheck(Expression f)
Create a predicate for checking validity of expressions.
Definition: utility.hh:283
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:64
auto transformTuple(F &&f, const std::tuple< T1... > &tuple1, const std::tuple< T2... > &tuple2) -> decltype(Imp::transformTupleHelper(std::forward< F >(f), tuple1, tuple2, std::index_sequence_for< T1... >{}))
Transform tuple value using a binary functor.
Definition: utility.hh:189
auto negatePredicate(Check check)
Negate given predicate.
Definition: utility.hh:308
Definition: polynomial.hh:17
Get last entry of type list.
Definition: utility.hh:226
Rotate type list by one, such that last entry is moved to first position.
Definition: utility.hh:255
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Aug 13, 22:30, 2024)