dune-functions  2.6-dev
differentiablefunction_imp.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_DIFFERENTIABLE_FUNCTION_IMP_HH
4 #define DUNE_FUNCTIONS_COMMON_DIFFERENTIABLE_FUNCTION_IMP_HH
5 
6 #include <dune/common/exceptions.hh>
7 #include <dune/common/concept.hh>
8 
10 
11 
12 namespace Dune {
13 namespace Functions {
14 namespace Imp {
15 
19 struct HasFreeDerivative
20 {
21  template<class F>
22  auto require(F&& f) -> decltype(
23  derivative(f)
24  );
25 };
26 
27 
28 
29 template<class Dummy, class F,
30  typename std::enable_if<
31  models< HasFreeDerivative, F>() , int>::type = 0>
32 auto derivativeIfImplemented(const F& f) -> decltype(derivative(f))
33 {
34  return derivative(f);
35 }
36 
37 
38 
39 template<class Dummy, class F,
40  typename std::enable_if<
41  not(models< HasFreeDerivative, F>()) , int>::type = 0>
42 Dummy derivativeIfImplemented(const F& f)
43 {
44  DUNE_THROW(Dune::NotImplemented, "Derivative not implemented");
45 }
46 
47 
48 
49 template<class Signature, class DerivativeInterface>
50 class DifferentiableFunctionWrapperInterface
51 {};
52 
53 // Interface of type erasure wrapper
54 //
55 // Notice that the basic interface of polymorphic classes (destructor, clone, ...)
56 // will be added by the type erasure foundation classes.
57 template<class Range, class Domain, class DerivativeInterface>
58 class DifferentiableFunctionWrapperInterface<Range(Domain), DerivativeInterface>
59 {
60 public:
61  virtual Range operator() (const Domain& x) const = 0;
62 
63  virtual DerivativeInterface derivative() const = 0;
64 };
65 
66 
67 
68 template<class Signature, class DerivativeInterface, class B>
69 class DifferentiableFunctionWrapperImplementation
70 {};
71 
72 // Implementation of type erasure wrapper
73 template<class Range, class Domain, class DerivativeInterface, class B>
74 class DifferentiableFunctionWrapperImplementation< Range(Domain), DerivativeInterface, B> :
75  public B
76 {
77 public:
78 
79  using B::B;
80  using Wrapped = typename B::Wrapped;
81 
82  virtual Range operator() (const Domain& x) const
83  {
84  return this->get()(x);
85  }
86 
87  virtual DerivativeInterface derivative() const
88  {
89  return derivativeIfImplemented<DerivativeInterface, Wrapped>(this->get());
90  }
91 };
92 
93 
94 
95 }}} // namespace Dune::Functions::Imp
96 
97 
98 
99 #endif // DUNE_FUNCTIONS_COMMON_DIFFERENTIABLE_FUNCTION_IMP_HH
Dune
Definition: polynomial.hh:7
Dune::Functions::derivative
TrigonometricFunction< K, -cosFactor, sinFactor > derivative(const TrigonometricFunction< K, sinFactor, cosFactor > &f)
Obtain derivative of TrigonometricFunction function.
Definition: trigonometricfunction.hh:38
type_traits.hh