dune-functions  2.7.1
signature.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_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 
14 
15 namespace Dune {
16 namespace Functions {
17 
23 template<typename F>
24 struct IsCallable;
25 
26 #ifndef DOXYGEN
27 template<typename F>
28 struct 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 
41 template<typename R, typename D>
42 struct IsCallable<R(D)>
43 {
44  enum { value = true };
45 };
46 
47 template<typename R, typename D>
48 struct IsCallable<R(*)(D)>
49 {
50  enum { value = true };
51 };
52 #endif
53 
59 template<class Signature, bool isCallable = IsCallable<Signature>::value >
60 struct SignatureTraits {};
61 
62 #ifndef DOXYGEN
64 template<class T>
65 struct SignatureTraits<T, true>
66  : public SignatureTraits<decltype(&T::operator()), true>
67 {};
68 
70 template <typename C, typename R, typename D>
71 struct SignatureTraits<R(C::*)(D) const, true>
72  : public SignatureTraits<R(D), true>
73 {};
74 
76 template <typename C, typename R, typename D>
77 struct SignatureTraits<R(C::*)(D), true>
78  : public SignatureTraits<R(D), true>
79 {};
80 
82 template <typename R, typename D>
83 struct SignatureTraits<R(*)(D), true>
84  : public SignatureTraits<R(D), true>
85 {};
86 
88 template<class R, class D>
89 struct 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 
105 template<class Signature, template<class> class DerivativeTraits=DefaultDerivativeTraits>
107 
117 template<class Range, class Domain, template<class> class DerivativeTraitsT>
118 struct SignatureTag<Range(Domain), DerivativeTraitsT>
119 {
120  using Signature = Range(Domain);
121 
122  template<class T>
123  using DerivativeTraits = DerivativeTraitsT<T>;
124 };
125 
126 
127 
136 template<class Range, class Domain, template<class> class DerivativeTraits>
137 auto derivativeSignatureTag(SignatureTag<Range(Domain), DerivativeTraits> tag)
138 {
139  using DerivativeRange = typename DerivativeTraits<Range(Domain)>::Range;
141 }
142 
143 
144 
158 template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
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
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
Definition: polynomial.hh:10
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
Definition: signature.hh:106
DerivativeTraitsT< T > DerivativeTraits
Definition: signature.hh:123
Range(Domain) Signature
Definition: signature.hh:120