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
11namespace AMDiS {
12namespace Recursive {
13
14template <class>
15struct Transform;
16
19
26template <class Out, class Op, class... In>
27void transform (Out& out, Op&& op, In const&... in)
28{
29 Transform<std::remove_const_t<Out>>::impl(out,op,in...);
30}
31
32
33template <class>
35{
36private:
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
84public:
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: Transform.hpp:35