Dune Core Modules (2.9.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 
11 namespace Dune {
12 namespace Functions {
13 
19 template<typename F>
20 struct IsCallable;
21 
22 #ifndef DOXYGEN
23 template<typename F>
24 struct 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 
37 template<typename R, typename D>
38 struct IsCallable<R(D)>
39 {
40  enum { value = true };
41 };
42 
43 template<typename R, typename D>
44 struct IsCallable<R(*)(D)>
45 {
46  enum { value = true };
47 };
48 #endif
49 
55 template<class Signature, bool isCallable = IsCallable<Signature>::value >
56 struct SignatureTraits {};
57 
58 #ifndef DOXYGEN
60 template<class T>
61 struct SignatureTraits<T, true>
62  : public SignatureTraits<decltype(&T::operator()), true>
63 {};
64 
66 template <typename C, typename R, typename D>
67 struct SignatureTraits<R(C::*)(D) const, true>
68  : public SignatureTraits<R(D), true>
69 {};
70 
72 template <typename C, typename R, typename D>
73 struct SignatureTraits<R(C::*)(D), true>
74  : public SignatureTraits<R(D), true>
75 {};
76 
78 template <typename R, typename D>
79 struct SignatureTraits<R(*)(D), true>
80  : public SignatureTraits<R(D), true>
81 {};
82 
84 template<class R, class D>
85 struct 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 
101 template<class Signature, template<class> class DerivativeTraits=DefaultDerivativeTraits>
102 struct SignatureTag;
103 
113 template<class Range, class Domain, template<class> class DerivativeTraitsT>
114 struct SignatureTag<Range(Domain), DerivativeTraitsT>
115 {
116  using Signature = Range(Domain);
117 
118  template<class T>
119  using DerivativeTraits = DerivativeTraitsT<T>;
120 };
121 
122 
123 
132 template<class Range, class Domain, template<class> class DerivativeTraits>
133 auto 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 
154 template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
155 auto 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:13
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.80.0 (Mar 28, 23:30, 2024)