AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
TreePath.hpp
1#pragma once
2
3#include <cassert>
4#include <sstream>
5#include <string>
6#include <type_traits>
7
8#include <dune/common/typetree/treepath.hh>
9
10#include <amdis/common/Apply.hpp>
11#include <amdis/common/ConceptsBase.hpp>
12#include <amdis/common/Literals.hpp>
13#include <amdis/common/Logical.hpp>
14
15namespace AMDiS {
16
17using RootTreePath = Dune::TypeTree::TreePath<>;
18
19namespace Concepts {
20
25namespace Definition
26{
27 template <class Index>
29 : std::is_integral<Index>
30 {};
31
32 template <class Index, Index I>
33 struct IsPreTreePath<std::integral_constant<Index, I>>
34 : std::is_integral<Index>
35 {};
36
37 template <class Index, Index... I>
38 struct IsPreTreePath<std::integer_sequence<Index, I...>>
39 : std::is_integral<Index>
40 {};
41
42 template <class... Indices>
43 struct IsPreTreePath<std::tuple<Indices...>>
44 : std::conjunction<std::is_integral<Indices>...>
45 {};
46
47 template <class TP>
49 : std::false_type
50 {};
51
52 template <class... Indices>
53 struct IsTreePath<Dune::TypeTree::TreePath<Indices...>>
54 : std::true_type
55 {};
56
57} // end namespace Definition
58
59template <class TP>
60constexpr bool PreTreePath = Definition::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
61
62template <class TP>
63using PreTreePath_t = bool_t<PreTreePath<TP>>;
64
67} // end namespace Concepts
68
69namespace Impl
70{
71 template <class Index,
72 std::enable_if_t<std::is_integral_v<Index>, int> = 0>
73 constexpr std::size_t treePathIndex(Index i)
74 {
75 return std::size_t(i);
76 }
77
78 template <class Index, Index i,
79 std::enable_if_t<std::is_integral_v<Index>, int> = 0>
80 constexpr auto treePathIndex(std::integral_constant<Index,i>)
81 {
82 return std::integral_constant<std::size_t,std::size_t(i)>{};
83 }
84
85} // end namespace Impl
86
87#ifdef DOXYGEN
88
90
111template <class PreTreePath>
112constexpr auto makeTreePath(PreTreePath tp);
113
114#else // DOXYGEN
115
116template <class... Indices>
117constexpr auto makeTreePath(Indices... ii)
118 -> decltype( Dune::TypeTree::treePath(Impl::treePathIndex(ii)...) )
119{
120 return Dune::TypeTree::treePath(Impl::treePathIndex(ii)...);
121}
122
123constexpr auto makeTreePath()
124{
125 return Dune::TypeTree::treePath();
126}
127
128template <class Index, Index... I>
129constexpr auto makeTreePath(std::integer_sequence<Index, I...>)
130{
131 return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
132}
133
134template <class... T>
135constexpr auto makeTreePath(std::tuple<T...> const& tp)
136{
137 return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
138}
139
140template <class... T>
141constexpr auto const& makeTreePath(Dune::TypeTree::TreePath<T...> const& tp)
142{
143 return tp;
144}
145
146template <std::size_t... I>
147constexpr auto makeTreePath(Dune::TypeTree::TreePath<Dune::index_constant<I>...> tp)
148{
149 return tp;
150}
151
152#endif // DOXYGEN
153
154
156template <char... digits>
157constexpr auto operator"" _tp()
158{
159 return Dune::TypeTree::treePath(std::integral_constant<std::size_t,Impl::char2digit(digits)>{}...);
160}
161
162
163// convert a treepath into a string, comma-separated
164template <class... T>
165std::string to_string(Dune::TypeTree::TreePath<T...> const& tp)
166{
167 auto entry = [&](auto i) { return std::to_string(std::size_t(tp[i])); };
168 auto first = [&] { return entry(std::integral_constant<std::size_t,0>()); };
169
170 return Ranges::applyIndices<1,sizeof...(T)>([&](auto... i) -> std::string {
171 return (first() +...+ ("," + entry(i)));
172 });
173}
174
175inline std::string to_string(Dune::TypeTree::TreePath<> const&)
176{
177 return "";
178}
179
180// convert a treepath into an array
181template <class... T>
182auto to_array(Dune::TypeTree::TreePath<T...> const& tp)
183{
184 return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
185 return std::array<std::size_t,sizeof...(T)>{std::size_t(tp[i])...};
186 });
187}
188
190template <class T0, class... T>
191auto pop_front(Dune::TypeTree::TreePath<T0,T...> const& tp)
192{
193 return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
194 return Dune::TypeTree::treePath(tp[index_t<i+1>{}]...);
195 });
196}
197
199template <class... T>
200requires (sizeof...(T)>0)
201auto pop_back(Dune::TypeTree::TreePath<T...> const& tp)
202{
203 return Ranges::applyIndices<sizeof...(T)-1>([&](auto... i) {
204 return Dune::TypeTree::treePath(tp[i]...);
205 });
206}
207
209template <class... S, class... T>
210auto cat(Dune::TypeTree::TreePath<S...> const& tp0, Dune::TypeTree::TreePath<T...> const& tp1)
211{
212 return Dune::TypeTree::join(tp0, tp1);
213}
214
215template<class First, class Second, REQUIRES(Concepts::PreTreePath<First> and Concepts::PreTreePath<Second>)>
216auto cat(First const& first, Second const& second)
217{
218 return cat(makeTreePath(first), makeTreePath(second));
219}
220
221} // end namespace AMDiS
Definition TreePath.hpp:50