DUNE PDELab (2.7)

signature.hh
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_SIGNATURE_HH
4#define DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
5
6#include <type_traits>
7#include <tuple>
8
9#include <dune/common/hybridutilities.hh>
10#include <dune/common/std/apply.hh>
11#include <dune/common/std/type_traits.hh>
12
13#include <dune/functions/common/defaultderivativetraits.hh>
14
15namespace Dune {
16namespace Functions {
17
23template<typename F>
25
26#ifndef DOXYGEN
27template<typename F>
28struct IsCallable
29{
30 struct yes { std::size_t dummy[2]; };
31 struct no { std::size_t dummy[1]; };
32
33 template<typename C>
34 static yes test(const decltype(&C::operator()) *);
35 template<typename C>
36 static no test(...);
37
38 enum { value = (sizeof(test<F>(0)) == sizeof(yes)) };
39};
40
41template<typename R, typename D>
42struct IsCallable<R(D)>
43{
44 enum { value = true };
45};
46
47template<typename R, typename D>
48struct IsCallable<R(*)(D)>
49{
50 enum { value = true };
51};
52#endif
53
59template<class Signature, bool isCallable = IsCallable<Signature>::value >
61
62#ifndef DOXYGEN
64template<class T>
65struct SignatureTraits<T, true>
66 : public SignatureTraits<decltype(&T::operator()), true>
67{};
68
70template <typename C, typename R, typename D>
71struct SignatureTraits<R(C::*)(D) const, true>
72 : public SignatureTraits<R(D), true>
73{};
74
76template <typename C, typename R, typename D>
77struct SignatureTraits<R(C::*)(D), true>
78 : public SignatureTraits<R(D), true>
79{};
80
82template <typename R, typename D>
83struct SignatureTraits<R(*)(D), true>
84 : public SignatureTraits<R(D), true>
85{};
86
88template<class R, class D>
89struct SignatureTraits<R(D), true>
90{
91 using Range = R;
92 using Domain = D;
93
94 using RawRange = typename std::decay<Range>::type;
95 using RawDomain = typename std::decay<Domain>::type;
96
97 using RawSignature = RawRange(RawDomain);
98
99 template<template<class> class DerivativeTraits=DefaultDerivativeTraits>
100 using DerivativeSignature = typename DerivativeTraits<RawSignature>::Range(Domain);
101};
102#endif
103
104
105template<class Signature, template<class> class DerivativeTraits=DefaultDerivativeTraits>
106struct SignatureTag;
107
117template<class Range, class Domain, template<class> class DerivativeTraitsT>
118struct SignatureTag<Range(Domain), DerivativeTraitsT>
119{
120 using Signature = Range(Domain);
121
122 template<class T>
123 using DerivativeTraits = DerivativeTraitsT<T>;
124};
125
126
127
136template<class Range, class Domain, template<class> class DerivativeTraits>
137auto derivativeSignatureTag(SignatureTag<Range(Domain), DerivativeTraits> tag)
138{
139 using DerivativeRange = typename DerivativeTraits<Range(Domain)>::Range;
140 return SignatureTag<DerivativeRange(Domain), DerivativeTraits>();
141}
142
143
144
158template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
159auto derivativeSignatureTags(Dune::Functions::SignatureTag<Signature, DerivativeTraits> tag)
160{
161// using namespace Dune::Hybrid;
162// using namespace Dune::Std;
163
164 return Hybrid::ifElse(Std::bool_constant<maxOrder==0>(), [&](auto id) {
165 // If maxOrder== 0 we just need the given SignatureTag
166 return std::make_tuple(tag);
167 }, [&](auto id) {
168 // else we first construct the tail tuple with SignatureTags for derivatives
169 // of order 1 to maxOrder
170 auto tailTagsTuple = derivativeSignatureTags<decltype((void)id,std::size_t(0))(maxOrder-1)>(derivativeSignatureTag(tag));
171 // and prepend this with the given SignatureTag.
172 // This is done by unpacking the tail tuple with apply().
173 return Std::apply([&](auto&&... tailTags){
174 return std::make_tuple(tag, tailTags...);
175 }, tailTagsTuple);
176 });
177}
178
179
180
181} // namespace Functions
182} // namespace Dune
183
184#endif // DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
std::integral_constant< bool, value > bool_constant
A template alias for std::integral_constant<bool, value>
Definition: type_traits.hh:118
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:46
auto derivativeSignatureTag(SignatureTag< Range(Domain), DerivativeTraits > tag)
Construct SignatureTag for derivative.
Definition: signature.hh:137
auto derivativeSignatureTags(Dune::Functions::SignatureTag< Signature, DerivativeTraits > tag)
Construct SignatureTags for derivatives.
Definition: signature.hh:159
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:355
Dune namespace.
Definition: alignedallocator.hh:14
Helper class to check that F is callable.
Definition: signature.hh:24
Helper class to deduce the signature of a callable.
Definition: signature.hh:60
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)