AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
TreePath.hpp
1 #pragma once
2 
3 #include <sstream>
4 #include <string>
5 #include <type_traits>
6 
7 #include <dune/common/version.hh>
8 #include <dune/common/std/apply.hh>
9 #include <dune/typetree/treepath.hh>
10 #include <dune/typetree/typetraits.hh>
11 
12 #include <amdis/common/Logical.hpp>
13 
14 namespace AMDiS
15 {
16  using RootTreePath = Dune::TypeTree::HybridTreePath<>;
17 
18  namespace Concepts
19  {
24  namespace Definition
25  {
26  template <class Index>
28  : std::is_integral<Index>
29  {};
30 
31  template <class Index, Index I>
32  struct IsPreTreePath<std::integral_constant<Index, I>>
33  : std::is_integral<Index>
34  {};
35 
36  template <class Index, Index... I>
37  struct IsPreTreePath<std::integer_sequence<Index, I...>>
38  : std::is_integral<Index>
39  {};
40 
41  template <class... Indices>
42  struct IsPreTreePath<std::tuple<Indices...>>
43  : std::conjunction<std::is_integral<Indices>...>
44  {};
45 
46  } // end namespace Definition
47 
48  template <class TP>
49  constexpr bool PreTreePath = Dune::TypeTree::IsTreePath<TP>::value || Definition::IsPreTreePath<TP>::value;
50 
51  template <class TP>
52  using PreTreePath_t = bool_t<PreTreePath<TP>>;
53 
56  } // end namespace Concepts
57 
58  namespace Impl
59  {
60  template <class Index,
61  std::enable_if_t<std::is_integral_v<Index>, int> = 0>
62  std::size_t treePathIndex(Index i)
63  {
64  return std::size_t(i);
65  }
66 
67  template <class Index, Index i,
68  std::enable_if_t<std::is_integral_v<Index>, int> = 0>
69  auto treePathIndex(std::integral_constant<Index,i>)
70  {
71  return std::integral_constant<std::size_t,std::size_t(i)>{};
72  }
73 
74  } // end namespace Impl
75 
76 #ifdef DOXYGEN
77 
79 
100  template <class PreTreePath>
101  auto makeTreePath(PreTreePath tp);
102 
103 #else // DOXYGEN
104 
105  template <class... Indices>
106  auto makeTreePath(Indices... ii)
107  -> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
108  {
109  return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
110  }
111 
112  inline auto makeTreePath()
113  {
114  return Dune::TypeTree::hybridTreePath();
115  }
116 
117  template <class Index, Index... I>
118  auto makeTreePath(std::integer_sequence<Index, I...>)
119  {
120  return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
121  }
122 
123  template <class... T>
124  auto makeTreePath(std::tuple<T...> const& tp)
125  {
126  return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
127  }
128 
129  template <class... T>
130  auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
131  {
132  return tp;
133  }
134 
135 #if DUNE_VERSION_LT(DUNE_TYPETREE,2,7)
136  template <std::size_t... I>
137  auto makeTreePath(Dune::TypeTree::TreePath<I...>)
138  {
139  return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
140  }
141 #else
142  template <std::size_t... I>
143  auto makeTreePath(Dune::TypeTree::StaticTreePath<I...>)
144  {
145  return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
146  }
147 #endif
148 
149 #endif // DOXYGEN
150 
151 
152  namespace Impl
153  {
154  template <class TreePath, std::size_t... I>
155  void printTreePath(std::ostream& os, TreePath const& tp, std::index_sequence<I...>)
156  {
157  (void)std::initializer_list<int>{
158  ((void)(os << treePathIndex(tp, std::integral_constant<std::size_t, I>{}) << ","), 0)...
159  };
160  }
161  }
162 
163  template <class T0, class... T>
164  std::string to_string(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
165  {
166  std::stringstream ss;
167  Impl::printTreePath(ss, tp, std::make_index_sequence<sizeof...(T)>{});
168  ss << Dune::TypeTree::treePathEntry<sizeof...(T)>(tp);
169  return ss.str();
170  }
171 
172  inline std::string to_string(Dune::TypeTree::HybridTreePath<> const&)
173  {
174  return "";
175  }
176 
177  namespace Impl
178  {
179  template <class TreePath, std::size_t... I>
180  std::array<std::size_t, sizeof...(I)> toArrayImpl(TreePath const& tp, std::index_sequence<I...>)
181  {
182  return {{std::size_t(Dune::TypeTree::treePathEntry<I>(tp))...}};
183  }
184  }
185 
186  template <class T0, class... T>
187  auto to_array(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
188  {
189  return Impl::toArrayImpl(tp, std::make_index_sequence<1+sizeof...(T)>{});
190  }
191 
192  inline std::array<std::size_t,1> to_array(Dune::TypeTree::HybridTreePath<> const&)
193  {
194  return {{0u}};
195  }
196 
197 
198  namespace Impl
199  {
200  template <class TreePath, std::size_t... I>
201  auto popFrontImpl(TreePath const& tp, std::index_sequence<I...>)
202  {
203  return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<I+1>(tp)...);
204  }
205 
206  template <class TreePath, std::size_t... I>
207  auto popBackImpl(TreePath const& tp, std::index_sequence<I...>)
208  {
209  return Dune::TypeTree::hybridTreePath(Dune::TypeTree::treePathEntry<I>(tp)...);
210  }
211  }
212 
213  template <class T0, class... T>
214  Dune::TypeTree::HybridTreePath<T...> pop_front(Dune::TypeTree::HybridTreePath<T0,T...> const& tp)
215  {
216  return Impl::popFrontImpl(tp, std::make_index_sequence<sizeof...(T)>{});
217  }
218 
219  template <class... T, class TN>
220  Dune::TypeTree::HybridTreePath<T...> pop_front(Dune::TypeTree::HybridTreePath<T...,TN> const& tp)
221  {
222  return Impl::popBackImpl(tp, std::make_index_sequence<sizeof...(T)>{});
223  }
224 
225  template <class... S, class... T>
226  Dune::TypeTree::HybridTreePath<S...,T...> cat(Dune::TypeTree::HybridTreePath<S...> const& tp0,
227  Dune::TypeTree::HybridTreePath<T...> const& tp1)
228  {
229  return Dune::TypeTree::HybridTreePath<S...,T...>(std::tuple_cat(tp0._data,tp1._data));
230  }
231 
232 } // end namespace AMDiS
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
std::integral_constant< bool, B > bool_t
A wrapper for bool types.
Definition: Logical.hpp:12