AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
TreePath.hpp
1#pragma once
2
3#include <cassert>
4#include <sstream>
5#include <string>
6#include <type_traits>
7
8#include <dune/common/version.hh>
9#include <dune/typetree/treepath.hh>
10#include <dune/typetree/typetraits.hh>
11
12#include <amdis/common/Apply.hpp>
13#include <amdis/common/Literals.hpp>
14#include <amdis/common/Logical.hpp>
15
16namespace AMDiS {
17
18using RootTreePath = Dune::TypeTree::HybridTreePath<>;
19
20namespace Concepts {
21
26namespace Definition
27{
28 template <class Index>
30 : std::is_integral<Index>
31 {};
32
33 template <class Index, Index I>
34 struct IsPreTreePath<std::integral_constant<Index, I>>
35 : std::is_integral<Index>
36 {};
37
38 template <class Index, Index... I>
39 struct IsPreTreePath<std::integer_sequence<Index, I...>>
40 : std::is_integral<Index>
41 {};
42
43 template <class... Indices>
44 struct IsPreTreePath<std::tuple<Indices...>>
45 : std::conjunction<std::is_integral<Indices>...>
46 {};
47
48} // end namespace Definition
49
50template <class TP>
51constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
52
53template <class TP>
54using PreTreePath_t = bool_t<PreTreePath<TP>>;
55
58} // end namespace Concepts
59
60namespace Impl
61{
62 template <class Index,
63 std::enable_if_t<std::is_integral_v<Index>, int> = 0>
64 constexpr std::size_t treePathIndex(Index i)
65 {
66 return std::size_t(i);
67 }
68
69 template <class Index, Index i,
70 std::enable_if_t<std::is_integral_v<Index>, int> = 0>
71 constexpr auto treePathIndex(std::integral_constant<Index,i>)
72 {
73 return std::integral_constant<std::size_t,std::size_t(i)>{};
74 }
75
76} // end namespace Impl
77
78#ifdef DOXYGEN
79
81
102template <class PreTreePath>
103constexpr auto makeTreePath(PreTreePath tp);
104
105#else // DOXYGEN
106
107template <class... Indices>
108constexpr auto makeTreePath(Indices... ii)
109 -> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
110{
111 return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
112}
113
114constexpr auto makeTreePath()
115{
116 return Dune::TypeTree::hybridTreePath();
117}
118
119template <class Index, Index... I>
120constexpr auto makeTreePath(std::integer_sequence<Index, I...>)
121{
122 return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
123}
124
125template <class... T>
126constexpr auto makeTreePath(std::tuple<T...> const& tp)
127{
128 return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
129}
130
131template <class... T>
132constexpr auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
133{
134 return tp;
135}
136
137template <std::size_t... I>
138constexpr auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
139{
140 return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
141}
142
143#endif // DOXYGEN
144
145
147template <char... digits>
148constexpr auto operator"" _tp()
149{
150 return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t,Impl::char2digit(digits)>{}...);
151}
152
153
154// convert a treepath into a string, comma-separated
155template <class... T>
156std::string to_string(Dune::TypeTree::HybridTreePath<T...> const& tp)
157{
158 auto entry = [&](auto i) { return std::to_string(std::size_t(Dune::TypeTree::treePathEntry<i>(tp))); };
159 auto first = [&] { return entry(std::integral_constant<std::size_t,0>()); };
160
161 return Ranges::applyIndices<1,sizeof...(T)>([&](auto... i) -> std::string {
162 return (first() +...+ ("," + entry(i)));
163 });
164}
165
166inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
167{
168 return "";
169}
170
171// convert a treepath into an array
172template <class... T>
173auto to_array(Dune::TypeTree::HybridTreePath<T...> const& tp)
174{
175 return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
176 return std::array<std::size_t,sizeof...(T)>{std::size_t(Dune::TypeTree::treePathEntry<i>(tp))...};
177 });
178}
179
181template <class T0, class... T>
182auto pop_front(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
183{
184 return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
185 return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i+1>(tp)...);
186 });
187}
188
190template <class... T, class TN>
191auto pop_back(Dune::TypeTree::HybridTreePath<T...,TN> const& tp)
192{
193 return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
194 return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i>(tp)...);
195 });
196}
197
199template <class... S, class... T>
200auto cat(Dune::TypeTree::HybridTreePath<S...> const& tp0, Dune::TypeTree::HybridTreePath<T...> const& tp1)
201{
202 return Dune::TypeTree::HybridTreePath<S...,T...>(std::tuple_cat(tp0._data,tp1._data));
203}
204
205} // end namespace AMDiS