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