AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
Transform.hpp
1 #pragma once
2 
3 #include <type_traits>
4 #include <utility>
5 #include <vector>
6 
7 #include <dune/common/typeutilities.hh>
8 #include <amdis/common/ForEach.hpp>
9 #include <amdis/common/StaticSize.hpp>
10 
11 namespace AMDiS {
12 namespace Recursive {
13 
14 template <class>
15 struct Transform;
16 
19 
26 template <class Out, class Op, class... In>
27 void transform (Out& out, Op&& op, In const&... in)
28 {
29  Transform<std::remove_const_t<Out>>::impl(out,op,in...);
30 }
31 
32 
33 template <class>
34 struct Transform
35 {
36 private:
37  // ranges with dynamic index access
38  template <class OutIter, class Op, class In0, class... InIter>
39  static void impl3 (OutIter d_first, Op&& op, In0 first0, In0 last0, InIter... first)
40  {
41  while (first0 != last0)
42  Recursive::transform(*d_first++, op, *first0++, *first++...);
43  }
44 
45  // ranges with dynamic index access
46  template <class Out, class Op, class In0, class... In,
47  class = decltype(std::begin(std::declval<Out>())),
48  class = decltype(std::begin(std::declval<In0>())),
49  class = decltype(std::end(std::declval<In0>())),
50  class = decltype((std::begin(std::declval<In>()),...))>
51  static void impl2 (Dune::PriorityTag<3>, Out& out, Op&& op, In0 const& in0,
52  In const&... in)
53  {
54  impl3(std::begin(out), op, std::begin(in0), std::end(in0), std::begin(in)...);
55  }
56 
57  // ranges with static index access
58  template <class Out, class Op, class... In,
59  class = decltype(std::declval<Out>()[std::integral_constant<std::size_t,0>{}])>
60  static void impl2 (Dune::PriorityTag<2>, Out& out, Op&& op, In const&... in)
61  {
62  Ranges::forIndices<static_size_v<Out>>([&](auto ii) {
63  Recursive::transform(out[ii], op, in[ii]...);
64  });
65  }
66 
67  // ranges with static getter access
68  template <class Out, class Op, class... In,
69  class = decltype(std::get<0>(std::declval<Out>()))>
70  static void impl2 (Dune::PriorityTag<1>, Out& out, Op&& op, In const&... in)
71  {
72  Ranges::forIndices<static_size_v<Out>>([&](auto ii) {
73  Recursive::transform(std::get<ii>(out), op, std::get<ii>(in)...);
74  });
75  }
76 
77  // no range
78  template <class Out, class Op, class... In>
79  static void impl2 (Dune::PriorityTag<0>, Out& out, Op&& op, In const&... in)
80  {
81  out = op(in...);
82  }
83 
84 public:
85  template <class Out, class Op, class... In>
86  static void impl (Out& out, Op&& op, In const&... in)
87  {
88  impl2(Dune::PriorityTag<5>{}, out, op, in...);
89  }
90 };
91 
92 }} // end namespace AMDiS::Recursive
Definition: AdaptBase.hpp:6
Definition: Transform.hpp:15