AMDiS  0.3
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/common/std/apply.hh>
10 #include <dune/typetree/treepath.hh>
11 #include <dune/typetree/typetraits.hh>
12 
13 #include <amdis/common/Apply.hpp>
14 #include <amdis/common/Literals.hpp>
15 #include <amdis/common/Logical.hpp>
16 
17 namespace AMDiS {
18 
19 using RootTreePath = Dune::TypeTree::HybridTreePath<>;
20 
21 namespace Concepts {
22 
27 namespace Definition
28 {
29  template <class Index>
31  : std::is_integral<Index>
32  {};
33 
34  template <class Index, Index I>
35  struct IsPreTreePath<std::integral_constant<Index, I>>
36  : std::is_integral<Index>
37  {};
38 
39  template <class Index, Index... I>
40  struct IsPreTreePath<std::integer_sequence<Index, I...>>
41  : std::is_integral<Index>
42  {};
43 
44  template <class... Indices>
45  struct IsPreTreePath<std::tuple<Indices...>>
46  : std::conjunction<std::is_integral<Indices>...>
47  {};
48 
49 } // end namespace Definition
50 
51 template <class TP>
52 constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
53 
54 template <class TP>
55 using PreTreePath_t = bool_t<PreTreePath<TP>>;
56 
59 } // end namespace Concepts
60 
61 namespace Impl
62 {
63  template <class Index,
64  std::enable_if_t<std::is_integral_v<Index>, int> = 0>
65  std::size_t treePathIndex(Index i)
66  {
67  return std::size_t(i);
68  }
69 
70  template <class Index, Index i,
71  std::enable_if_t<std::is_integral_v<Index>, int> = 0>
72  auto treePathIndex(std::integral_constant<Index,i>)
73  {
74  return std::integral_constant<std::size_t,std::size_t(i)>{};
75  }
76 
77 } // end namespace Impl
78 
79 #ifdef DOXYGEN
80 
82 
103 template <class PreTreePath>
104 auto makeTreePath(PreTreePath tp);
105 
106 #else // DOXYGEN
107 
108 template <class... Indices>
109 auto makeTreePath(Indices... ii)
110  -> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
111 {
112  return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
113 }
114 
115 inline auto makeTreePath()
116 {
117  return Dune::TypeTree::hybridTreePath();
118 }
119 
120 template <class Index, Index... I>
121 auto makeTreePath(std::integer_sequence<Index, I...>)
122 {
123  return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
124 }
125 
126 template <class... T>
127 auto makeTreePath(std::tuple<T...> const& tp)
128 {
129  return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
130 }
131 
132 template <class... T>
133 auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
134 {
135  return tp;
136 }
137 
138 #if DUNE_VERSION_LT(DUNE_TYPETREE,2,7)
139 template <std::size_t... I>
140 auto makeTreePath(Dune::TypeTree::TreePath<I...>)
141 {
142  return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
143 }
144 #else
145 template <std::size_t... I>
146 auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
147 {
148  return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
149 }
150 #endif
151 
152 #endif // DOXYGEN
153 
154 
156 template <char... digits>
157 constexpr auto operator"" _tp()
158 {
159  return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t,Impl::char2digit(digits)>{}...);
160 }
161 
162 
163 // convert a treepath into a string, comma-separated
164 template <class... T>
165 std::string to_string(Dune::TypeTree::HybridTreePath<T...> const& tp)
166 {
167  auto entry = [&](auto i) { return std::to_string(std::size_t(Dune::TypeTree::treePathEntry<i>(tp))); };
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 
175 inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
176 {
177  return "";
178 }
179 
180 // convert a treepath into an array
181 template <class... T>
182 auto to_array(Dune::TypeTree::HybridTreePath<T...> const& tp)
183 {
184  return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
185  return std::array<std::size_t,sizeof...(T)>{std::size_t(Dune::TypeTree::treePathEntry<i>(tp))...};
186  });
187 }
188 
190 template <class T0, class... T>
191 auto pop_front(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
192 {
193  return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
194  return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i+1>(tp)...);
195  });
196 }
197 
199 template <class... T, class TN>
200 auto pop_back(Dune::TypeTree::HybridTreePath<T...,TN> const& tp)
201 {
202  return Ranges::applyIndices<sizeof...(T)>([&](auto... i) {
203  return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<i>(tp)...);
204  });
205 }
206 
208 template <class... S, class... T>
209 auto cat(Dune::TypeTree::HybridTreePath<S...> const& tp0, Dune::TypeTree::HybridTreePath<T...> const& tp1)
210 {
211  return Dune::TypeTree::HybridTreePath<S...,T...>(std::tuple_cat(tp0._data,tp1._data));
212 }
213 
214 } // end namespace AMDiS
auto pop_back(Dune::TypeTree::HybridTreePath< T..., TN > const &tp)
Extract the last entry in the treepath.
Definition: TreePath.hpp:200
std::index_sequence< I... > Indices
class that represents a sequence of indices
Definition: Index.hpp:40
Definition: FieldMatVec.hpp:12
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
auto cat(Dune::TypeTree::HybridTreePath< S... > const &tp0, Dune::TypeTree::HybridTreePath< T... > const &tp1)
Concatenate two treepaths.
Definition: TreePath.hpp:209
auto pop_front(Dune::TypeTree::HybridTreePath< T0, T... > const &tp)
Extract the first entry in the treepath.
Definition: TreePath.hpp:191
std::integral_constant< bool, B > bool_t
A wrapper for bool types.
Definition: Logical.hpp:12