AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
Composer.hpp
1 #pragma once
2 
3 #include <tuple>
4 #include <type_traits>
5 
6 #include <dune/common/std/apply.hh>
7 
8 #include <amdis/common/Apply.hpp>
9 #include <amdis/common/Concepts.hpp>
10 #include <amdis/common/Logical.hpp>
11 #include <amdis/operations/Basic.hpp>
12 
13 namespace AMDiS
14 {
15  namespace Operation
16  {
18 
30  template <class F, class... Gs>
31  struct Composer
32  {
33  template <class F_, class... Gs_,
35  constexpr Composer(F_&& f, Gs_&&... gs)
36  : f_(FWD(f))
37  , gs_(FWD(gs)...)
38  {}
39 
40  template <class... Ts>
41  constexpr auto operator()(Ts const&... args) const
42  {
43  auto eval = [&](auto const& g) { return g(args...); };
44  return Tools::apply([&,this](auto const&... gs) { return f_(eval(gs)...); }, gs_);
45  }
46 
47  F f_;
48  std::tuple<Gs...> gs_;
49  };
50 
51 #ifndef DOXYGEN
52  template <class F, class... Gs>
54  {
55  using type = Composer<F, Gs...>;
56 
57  template <class F_, class... Gs_>
58  static constexpr type build(F_&& f, Gs_&&... gs)
59  {
60  return type{FWD(f), FWD(gs)...};
61  }
62  };
63 #endif
64 
66  template <class F, class... Gs>
67  constexpr auto compose(F&& f, Gs&&... gs)
68  {
69  return ComposerBuilder<TYPEOF(f), TYPEOF(gs)...>::build(FWD(f), FWD(gs)...);
70  }
71 
72  // Polynomial order or composed function combines the orders of the sub-functions
73  template <class F, class... Gs, class... Int,
74  REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(Gs)>
75  && (Concepts::HasFunctorOrder<Gs,sizeof...(Int)> &&...))>
76  int order(Composer<F,Gs...> const& c, Int... degrees)
77  {
78  auto deg = [&](auto const& g) { return order(g, int(degrees)...); };
79  return Tools::apply([&](auto const&... gs) { return order(c.f_, deg(gs)...); }, c.gs_);
80  }
81 
84  template <int J, class F, class... Gs>
85  auto partial(Composer<F,Gs...> const& c, index_t<J> _j);
86 
87 
88 #ifndef DOXYGEN
89  // some specialization for the composer
90 
91  // id(g) => g
92  template <class F>
93  struct ComposerBuilder<Id, F>
94  {
95  using type = F;
96 
97  template <class F_>
98  static constexpr F build(F_&& f)
99  {
100  return F{FWD(f)};
101  }
102  };
103 #endif
104 
105  } // end namespace Operation
106 } // end namespace AMDiS
Composition of Functors.
Definition: Composer.hpp:31
A variadic type list.
Definition: TypeTraits.hpp:88
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
auto order(F const &f) -> decltype(&F::operator(), f.order())
polynomial order of functions
Definition: Order.hpp:11
constexpr bool Similar
Types are the same, up to decay of qualifiers.
Definition: Concepts.hpp:108
std::integral_constant< std::size_t, I > index_t
A wrapper for std::size_t type.
Definition: Index.hpp:31
Definition: Composer.hpp:53
(Unary-)Functor representing the identity
Definition: Basic.hpp:64