Dune Core Modules (2.8.0)

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/functions/common/defaultderivativetraits.hh>
10
11namespace Dune {
12namespace Functions {
13
19template<typename F>
21
22#ifndef DOXYGEN
23template<typename F>
24struct IsCallable
25{
26 struct yes { std::size_t dummy[2]; };
27 struct no { std::size_t dummy[1]; };
28
29 template<typename C>
30 static yes test(const decltype(&C::operator()) *);
31 template<typename C>
32 static no test(...);
33
34 enum { value = (sizeof(test<F>(0)) == sizeof(yes)) };
35};
36
37template<typename R, typename D>
38struct IsCallable<R(D)>
39{
40 enum { value = true };
41};
42
43template<typename R, typename D>
44struct IsCallable<R(*)(D)>
45{
46 enum { value = true };
47};
48#endif
49
55template<class Signature, bool isCallable = IsCallable<Signature>::value >
57
58#ifndef DOXYGEN
60template<class T>
61struct SignatureTraits<T, true>
62 : public SignatureTraits<decltype(&T::operator()), true>
63{};
64
66template <typename C, typename R, typename D>
67struct SignatureTraits<R(C::*)(D) const, true>
68 : public SignatureTraits<R(D), true>
69{};
70
72template <typename C, typename R, typename D>
73struct SignatureTraits<R(C::*)(D), true>
74 : public SignatureTraits<R(D), true>
75{};
76
78template <typename R, typename D>
79struct SignatureTraits<R(*)(D), true>
80 : public SignatureTraits<R(D), true>
81{};
82
84template<class R, class D>
85struct SignatureTraits<R(D), true>
86{
87 using Range = R;
88 using Domain = D;
89
90 using RawRange = typename std::decay<Range>::type;
91 using RawDomain = typename std::decay<Domain>::type;
92
93 using RawSignature = RawRange(RawDomain);
94
95 template<template<class> class DerivativeTraits=DefaultDerivativeTraits>
96 using DerivativeSignature = typename DerivativeTraits<RawSignature>::Range(Domain);
97};
98#endif
99
100
101template<class Signature, template<class> class DerivativeTraits=DefaultDerivativeTraits>
102struct SignatureTag;
103
113template<class Range, class Domain, template<class> class DerivativeTraitsT>
114struct SignatureTag<Range(Domain), DerivativeTraitsT>
115{
116 using Signature = Range(Domain);
117
118 template<class T>
119 using DerivativeTraits = DerivativeTraitsT<T>;
120};
121
122
123
132template<class Range, class Domain, template<class> class DerivativeTraits>
133auto derivativeSignatureTag(SignatureTag<Range(Domain), DerivativeTraits> tag)
134{
135 using DerivativeRange = typename DerivativeTraits<Range(Domain)>::Range;
136 return SignatureTag<DerivativeRange(Domain), DerivativeTraits>();
137}
138
139
140
154template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
155auto derivativeSignatureTags(Dune::Functions::SignatureTag<Signature, DerivativeTraits> tag)
156{
157 if constexpr (maxOrder==0) {
158 // If maxOrder== 0 we just need the given SignatureTag
159 return std::make_tuple(tag);
160 } else {
161 // else we first construct the tail tuple with SignatureTags for derivatives
162 // of order 1 to maxOrder
163 auto tailTagsTuple = derivativeSignatureTags<std::size_t(maxOrder-1)>(derivativeSignatureTag(tag));
164 // and prepend this with the given SignatureTag.
165 // This is done by unpacking the tail tuple with apply().
166 return std::apply([&](auto&&... tailTags){
167 return std::make_tuple(tag, tailTags...);
168 }, tailTagsTuple);
169 }
170}
171
172
173
174} // namespace Functions
175} // namespace Dune
176
177#endif // DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
auto derivativeSignatureTag(SignatureTag< Range(Domain), DerivativeTraits > tag)
Construct SignatureTag for derivative.
Definition: signature.hh:133
auto derivativeSignatureTags(Dune::Functions::SignatureTag< Signature, DerivativeTraits > tag)
Construct SignatureTags for derivatives.
Definition: signature.hh:155
Dune namespace.
Definition: alignedallocator.hh:11
Helper class to check that F is callable.
Definition: signature.hh:20
Helper class to deduce the signature of a callable.
Definition: signature.hh:56
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 22, 23:33, 2024)