dune-typetree  2.7.1
treepath.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=8 sw=2 sts=2:
3 
4 #ifndef DUNE_TYPETREE_TREEPATH_HH
5 #define DUNE_TYPETREE_TREEPATH_HH
6 
7 #include <cstddef>
8 #include <iostream>
9 
10 #include <dune/common/documentation.hh>
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/indices.hh>
13 #include <dune/common/hybridutilities.hh>
14 
16 #include <dune/typetree/utility.hh>
17 
18 
19 namespace Dune {
20  namespace TypeTree {
21 
22  template<typename... T>
24 
28 
29  namespace TreePathType {
31  }
32 
33  template<typename>
34  struct TreePathSize;
35 
36  template<typename,std::size_t>
38 
39  template<typename,std::size_t>
41 
42  template<typename>
43  struct TreePathBack;
44 
45  template<typename>
46  struct TreePathFront;
47 
48  template<typename, std::size_t...>
50 
51  template<typename>
53 
54  template<typename, typename>
56 
57  template<std::size_t... i>
58  void print_tree_path(std::ostream& os)
59  {}
60 
61  template<std::size_t k, std::size_t... i>
62  void print_tree_path(std::ostream& os)
63  {
64  os << k << " ";
65  print_tree_path<i...>(os);
66  }
67 
69 
77  template<typename... T>
78  class HybridTreePath
79  {
80 
81  public:
82 
84  using index_sequence = std::index_sequence_for<T...>;
85 
87  constexpr HybridTreePath()
88  {}
89 
90  constexpr HybridTreePath(const HybridTreePath& tp) = default;
91  constexpr HybridTreePath(HybridTreePath&& tp) = default;
92 
94  explicit constexpr HybridTreePath(std::tuple<T...> t)
95  : _data(t)
96  {}
97 
99  template<typename... U, typename std::enable_if<(sizeof...(T) > 0 && sizeof...(U) == sizeof...(T)),bool>::type = true>
100  explicit constexpr HybridTreePath(U... t)
101  : _data(t...)
102  {}
103 
105  constexpr static index_sequence enumerate()
106  {
107  return {};
108  }
109 
111  constexpr static std::size_t size()
112  {
113  return sizeof...(T);
114  }
115 
117  template<std::size_t i>
118  constexpr auto operator[](Dune::index_constant<i> pos) const
119  {
120  return std::get<i>(_data);
121  }
122 
124  constexpr std::size_t operator[](std::size_t pos) const
125  {
126  std::size_t entry = 0;
127  Dune::Hybrid::forEach(enumerate(), [&] (auto i) {
128  if (i==pos)
129  entry = this->element(i);
130  });
131  return entry;
132  }
133 
135  template<std::size_t i>
136  constexpr auto element(Dune::index_constant<i> pos = {}) const
137  {
138  return std::get<i>(_data);
139  }
140 
142  constexpr std::size_t element(std::size_t pos) const
143  {
144  std::size_t entry = 0;
145  Dune::Hybrid::forEach(enumerate(), [&] (auto i) {
146  if (i==pos)
147  entry = this->element(i);
148  });
149  return entry;
150  }
151 
153  auto back() const
154  {
155  return std::get<sizeof...(T)-1>(_data);
156  }
157 
158 #ifndef DOXYGEN
159 
160  // I can't be bothered to make all the external accessors friends of HybridTreePath,
161  // so we'll only hide the data tuple from the user in Doxygen.
162 
163  using Data = std::tuple<T...>;
164  Data _data;
165 
166 #endif // DOXYGEN
167 
168  };
169 
170 
172 
176  template<typename... T>
177  constexpr HybridTreePath<T...> hybridTreePath(const T&... t)
178  {
179  return HybridTreePath<T...>(t...);
180  }
181 
183 
187  template<typename... T>
188  constexpr HybridTreePath<T...> treePath(const T&... t)
189  {
190  return HybridTreePath<T...>(t...);
191  }
192 
193 
195  template<typename... T>
196  constexpr std::size_t treePathSize(const HybridTreePath<T...>&)
197  {
198  return sizeof...(T);
199  }
200 
202 
218  template<std::size_t i, typename... T>
219  constexpr auto treePathEntry(const HybridTreePath<T...>& tp, index_constant<i> = {})
220  -> typename std::decay<decltype(std::get<i>(tp._data))>::type
221  {
222  return std::get<i>(tp._data);
223  }
224 
226 
241  template<std::size_t i,typename... T>
242  constexpr std::size_t treePathIndex(const HybridTreePath<T...>& tp, index_constant<i> = {})
243  {
244  return std::get<i>(tp._data);
245  }
246 
248 
253  template<typename... T, typename std::enable_if<(sizeof...(T) > 0),bool>::type = true>
254  constexpr auto back(const HybridTreePath<T...>& tp)
255  -> decltype(treePathEntry<sizeof...(T)-1>(tp))
256  {
257  return treePathEntry<sizeof...(T)-1>(tp);
258  }
259 
261 
266  template<typename... T>
267  constexpr auto front(const HybridTreePath<T...>& tp)
268  -> decltype(treePathEntry<0>(tp))
269  {
270  return treePathEntry<0>(tp);
271  }
272 
274 
277  template<typename... T>
278  constexpr HybridTreePath<T...,std::size_t> push_back(const HybridTreePath<T...>& tp, std::size_t i)
279  {
280  return HybridTreePath<T...,std::size_t>(std::tuple_cat(tp._data,std::make_tuple(i)));
281  }
282 
284 
298  template<std::size_t i, typename... T>
299  constexpr HybridTreePath<T...,index_constant<i>> push_back(const HybridTreePath<T...>& tp, index_constant<i> i_ = {})
300  {
301  return HybridTreePath<T...,index_constant<i> >(std::tuple_cat(tp._data,std::make_tuple(i_)));
302  }
303 
305 
308  template<typename... T>
309  constexpr HybridTreePath<std::size_t,T...> push_front(const HybridTreePath<T...>& tp, std::size_t element)
310  {
311  return HybridTreePath<std::size_t,T...>(std::tuple_cat(std::make_tuple(element),tp._data));
312  }
313 
315 
329  template<std::size_t i, typename... T>
330  constexpr HybridTreePath<index_constant<i>,T...> push_front(const HybridTreePath<T...>& tp, index_constant<i> _i = {})
331  {
332  return HybridTreePath<index_constant<i>,T...>(std::tuple_cat(std::make_tuple(_i),tp._data));
333  }
334 
335 
336  template<std::size_t... i>
337  struct TreePathSize<HybridTreePath<index_constant<i>...> >
338  : public index_constant<sizeof...(i)>
339  {};
340 
341 
342  template<std::size_t k, std::size_t... i>
343  struct TreePathPushBack<HybridTreePath<index_constant<i>...>,k>
344  {
345  typedef HybridTreePath<index_constant<i>...,index_constant<k>> type;
346  };
347 
348  template<std::size_t k, std::size_t... i>
349  struct TreePathPushFront<HybridTreePath<index_constant<i>...>,k>
350  {
351  typedef HybridTreePath<index_constant<k>,index_constant<i>...> type;
352  };
353 
354  template<std::size_t k>
355  struct TreePathBack<HybridTreePath<index_constant<k>>>
356  : public index_constant<k>
357  {};
358 
359  template<std::size_t j, std::size_t k, std::size_t... l>
360  struct TreePathBack<HybridTreePath<index_constant<j>,index_constant<k>,index_constant<l>...>>
361  : public TreePathBack<HybridTreePath<index_constant<k>,index_constant<l>...>>
362  {};
363 
364  template<std::size_t k, std::size_t... i>
365  struct TreePathFront<HybridTreePath<index_constant<k>,index_constant<i>...>>
366  : public index_constant<k>
367  {};
368 
369  template<std::size_t k, std::size_t... i>
370  struct TreePathPopBack<HybridTreePath<index_constant<k>>,i...>
371  {
373  };
374 
375  template<std::size_t j,
376  std::size_t k,
377  std::size_t... l,
378  std::size_t... i>
379  struct TreePathPopBack<HybridTreePath<index_constant<j>,index_constant<k>,index_constant<l>...>,i...>
380  : public TreePathPopBack<HybridTreePath<index_constant<k>,index_constant<l>...>,i...,j>
381  {};
382 
383  template<std::size_t k, std::size_t... i>
384  struct TreePathPopFront<HybridTreePath<index_constant<k>,index_constant<i>...> >
385  {
387  };
388 
389  template<std::size_t... i, std::size_t... k>
390  struct TreePathConcat<HybridTreePath<index_constant<i>...>,HybridTreePath<index_constant<k>...> >
391  {
392  typedef HybridTreePath<index_constant<i>...,index_constant<k>...> type;
393  };
394 
395 #ifndef DOXYGEN
396 
397  namespace impl {
398 
399  // end of recursion
400  template<std::size_t i, typename... T>
401  typename std::enable_if<
402  (i == sizeof...(T))
403  >::type
404  print_hybrid_tree_path(std::ostream& os, const HybridTreePath<T...>& tp, index_constant<i> _i)
405  {}
406 
407  // print current entry and recurse
408  template<std::size_t i, typename... T>
409  typename std::enable_if<
410  (i < sizeof...(T))
411  >::type
412  print_hybrid_tree_path(std::ostream& os, const HybridTreePath<T...>& tp, index_constant<i> _i)
413  {
414  os << treePathIndex(tp,_i) << " ";
415  print_hybrid_tree_path(os,tp,index_constant<i+1>{});
416  }
417 
418  } // namespace impl
419 
420 #endif // DOXYGEN
421 
423  template<typename... T>
424  std::ostream& operator<<(std::ostream& os, const HybridTreePath<T...>& tp)
425  {
426  os << "HybridTreePath< ";
427  impl::print_hybrid_tree_path(os, tp, index_constant<0>{});
428  os << ">";
429  return os;
430  }
431 
432  template<std::size_t... i>
433  using TreePath [[deprecated("use StaticTreePath, this type will be removed after DUNE 2.7")]] = HybridTreePath<Dune::index_constant<i>...>;
434 
435  template<std::size_t... i>
437 
439 
440  } // namespace TypeTree
441 } //namespace Dune
442 
443 #endif // DUNE_TYPETREE_TREEPATH_HH
Dune::TypeTree::operator<<
std::ostream & operator<<(std::ostream &os, const HybridTreePath< T... > &tp)
Dumps a HybridTreePath to a stream.
Definition: treepath.hh:424
Dune::TypeTree::HybridTreePath::back
auto back() const
Get the last index value.
Definition: treepath.hh:153
Dune::TypeTree::HybridTreePath::HybridTreePath
constexpr HybridTreePath(U... t)
Constructor from arguments.
Definition: treepath.hh:100
Dune::TypeTree::HybridTreePath::HybridTreePath
constexpr HybridTreePath()
Default constructor.
Definition: treepath.hh:87
Dune::TypeTree::TreePathFront
Definition: treepath.hh:46
Dune::TypeTree::TreePathSize
Definition: treepath.hh:34
Dune::TypeTree::TreePathPushFront< HybridTreePath< index_constant< i >... >, k >::type
HybridTreePath< index_constant< k >, index_constant< i >... > type
Definition: treepath.hh:351
utility.hh
Dune::TypeTree::HybridTreePath::size
constexpr static std::size_t size()
Get the size (length) of this path.
Definition: treepath.hh:111
Dune::TypeTree::HybridTreePath::index_sequence
std::index_sequence_for< T... > index_sequence
An index_sequence for the entries in this HybridTreePath.
Definition: treepath.hh:84
Dune::TypeTree::TreePathPopFront< HybridTreePath< index_constant< k >, index_constant< i >... > >::type
HybridTreePath< index_constant< i >... > type
Definition: treepath.hh:386
Dune::TypeTree::TreePathPopFront
Definition: treepath.hh:52
Dune::TypeTree::treePath
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:188
Dune::TypeTree::treePathSize
constexpr std::size_t treePathSize(const HybridTreePath< T... > &)
Returns the size (number of components) of the given HybridTreePath.
Definition: treepath.hh:196
Dune::TypeTree::TreePathBack
Definition: treepath.hh:43
Dune::TypeTree::HybridTreePath::element
constexpr auto element(Dune::index_constant< i > pos={}) const
Get the last index value.
Definition: treepath.hh:136
Dune::TypeTree::treePathEntry
constexpr auto treePathEntry(const HybridTreePath< T... > &tp, index_constant< i >={}) -> typename std::decay< decltype(std::get< i >(tp._data))>::type
Returns a copy of the i-th element of the HybridTreePath.
Definition: treepath.hh:219
Dune::TypeTree::TreePathType::Type
Type
Definition: treepath.hh:30
Dune::TypeTree::print_tree_path
void print_tree_path(std::ostream &os)
Definition: treepath.hh:58
Dune::TypeTree::front
constexpr auto front(const HybridTreePath< T... > &tp) -> decltype(treePathEntry< 0 >(tp))
Returns a copy of the first element of the HybridTreePath.
Definition: treepath.hh:267
Dune::TypeTree::HybridTreePath
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:23
fixedcapacitystack.hh
Dune::TypeTree::back
constexpr auto back(const HybridTreePath< T... > &tp) -> decltype(treePathEntry< sizeof...(T) -1 >(tp))
Returns a copy of the last element of the HybridTreePath.
Definition: treepath.hh:254
Dune::TypeTree::push_front
constexpr HybridTreePath< std::size_t, T... > push_front(const HybridTreePath< T... > &tp, std::size_t element)
Prepends a run time index to a HybridTreePath.
Definition: treepath.hh:309
Dune::TypeTree::HybridTreePath::enumerate
constexpr static index_sequence enumerate()
Returns an index_sequence for enumerating the components of this HybridTreePath.
Definition: treepath.hh:105
Dune::TypeTree::TreePathPushBack
Definition: treepath.hh:37
Dune::TypeTree::TreePathType::dynamic
@ dynamic
Definition: treepath.hh:30
Dune::TypeTree::push_back
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:278
Dune
Definition: accumulate_static.hh:13
Dune::TypeTree::HybridTreePath::HybridTreePath
constexpr HybridTreePath(std::tuple< T... > t)
Constructor from a std::tuple
Definition: treepath.hh:94
Dune::TypeTree::TreePathConcat
Definition: treepath.hh:55
Dune::TypeTree::treePathIndex
constexpr std::size_t treePathIndex(const HybridTreePath< T... > &tp, index_constant< i >={})
Returns the index value of the i-th element of the HybridTreePath.
Definition: treepath.hh:242
Dune::TypeTree::TreePathPopBack< HybridTreePath< index_constant< k > >, i... >::type
HybridTreePath< index_constant< i >... > type
Definition: treepath.hh:372
Dune::TypeTree::HybridTreePath::element
constexpr std::size_t element(std::size_t pos) const
Get the index value at position pos.
Definition: treepath.hh:142
Dune::TypeTree::hybridTreePath
constexpr HybridTreePath< T... > hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:177
Dune::TypeTree::TreePathPopBack
Definition: treepath.hh:49
Dune::TypeTree::TreePathPushFront
Definition: treepath.hh:40
Dune::TypeTree::HybridTreePath::operator[]
constexpr auto operator[](Dune::index_constant< i > pos) const
Get the index value at position pos.
Definition: treepath.hh:118
Dune::TypeTree::TreePathPushBack< HybridTreePath< index_constant< i >... >, k >::type
HybridTreePath< index_constant< i >..., index_constant< k > > type
Definition: treepath.hh:345
Dune::TypeTree::HybridTreePath::operator[]
constexpr std::size_t operator[](std::size_t pos) const
Get the index value at position pos.
Definition: treepath.hh:124
Dune::TypeTree::TreePathType::fullyStatic
@ fullyStatic
Definition: treepath.hh:30
Dune::TypeTree::TreePathConcat< HybridTreePath< index_constant< i >... >, HybridTreePath< index_constant< k >... > >::type
HybridTreePath< index_constant< i >..., index_constant< k >... > type
Definition: treepath.hh:392