Dune Core Modules (2.9.0)

treepath.hh
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
12#include <dune/common/indices.hh>
13#include <dune/common/hybridutilities.hh>
14
15#include <dune/typetree/fixedcapacitystack.hh>
16#include <dune/typetree/utility.hh>
17
18
19namespace Dune {
20 namespace TypeTree {
21
22 template<typename... T>
23 class HybridTreePath;
24
28
29 namespace TreePathType {
30 enum Type { fullyStatic, dynamic };
31 }
32
33 template<typename>
34 struct TreePathSize;
35
36 template<typename,std::size_t>
37 struct TreePathPushBack;
38
39 template<typename,std::size_t>
40 struct TreePathPushFront;
41
42 template<typename>
43 struct TreePathBack;
44
45 template<typename>
46 struct TreePathFront;
47
48 template<typename, std::size_t...>
49 struct TreePathPopBack;
50
51 template<typename>
52 struct TreePathPopFront;
53
54 template<typename, typename>
55 struct TreePathConcat;
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>
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
93 constexpr HybridTreePath& operator=(const HybridTreePath& tp) = default;
94 constexpr HybridTreePath& operator=(HybridTreePath&& tp) = default;
95
97 explicit constexpr HybridTreePath(std::tuple<T...> t)
98 : _data(t)
99 {}
100
102 template<typename... U, typename std::enable_if<(sizeof...(T) > 0 && sizeof...(U) == sizeof...(T)),bool>::type = true>
103 explicit constexpr HybridTreePath(U... t)
104 : _data(t...)
105 {}
106
108 constexpr static index_sequence enumerate()
109 {
110 return {};
111 }
112
114 constexpr static std::size_t size()
115 {
116 return sizeof...(T);
117 }
118
120 template<std::size_t i>
122 {
123 return std::get<i>(_data);
124 }
125
127 constexpr std::size_t operator[](std::size_t pos) const
128 {
129 std::size_t entry = 0;
130 Dune::Hybrid::forEach(enumerate(), [&] (auto i) {
131 if (i==pos)
132 entry = this->element(i);
133 });
134 return entry;
135 }
136
138 template<std::size_t i>
139 constexpr auto element(Dune::index_constant<i> pos = {}) const
140 {
141 return std::get<i>(_data);
142 }
143
145 constexpr std::size_t element(std::size_t pos) const
146 {
147 std::size_t entry = 0;
148 Dune::Hybrid::forEach(enumerate(), [&] (auto i) {
149 if (i==pos)
150 entry = this->element(i);
151 });
152 return entry;
153 }
154
156 auto back() const
157 {
158 return std::get<sizeof...(T)-1>(_data);
159 }
160
161#ifndef DOXYGEN
162
163 // I can't be bothered to make all the external accessors friends of HybridTreePath,
164 // so we'll only hide the data tuple from the user in Doxygen.
165
166 using Data = std::tuple<T...>;
167 Data _data;
168
169#endif // DOXYGEN
170
171 };
172
173
175
179 template<typename... T>
180 constexpr HybridTreePath<T...> hybridTreePath(const T&... t)
181 {
182 return HybridTreePath<T...>(t...);
183 }
184
186
190 template<typename... T>
191 constexpr HybridTreePath<T...> treePath(const T&... t)
192 {
193 return HybridTreePath<T...>(t...);
194 }
195
196
198 template<typename... T>
199 constexpr std::size_t treePathSize(const HybridTreePath<T...>&)
200 {
201 return sizeof...(T);
202 }
203
205
221 template<std::size_t i, typename... T>
222 constexpr auto treePathEntry(const HybridTreePath<T...>& tp, index_constant<i> = {})
223 -> typename std::decay<decltype(std::get<i>(tp._data))>::type
224 {
225 return std::get<i>(tp._data);
226 }
227
229
244 template<std::size_t i,typename... T>
245 constexpr std::size_t treePathIndex(const HybridTreePath<T...>& tp, index_constant<i> = {})
246 {
247 return std::get<i>(tp._data);
248 }
249
251
256 template<typename... T, typename std::enable_if<(sizeof...(T) > 0),bool>::type = true>
257 constexpr auto back(const HybridTreePath<T...>& tp)
258 -> decltype(treePathEntry<sizeof...(T)-1>(tp))
259 {
260 return treePathEntry<sizeof...(T)-1>(tp);
261 }
262
264
269 template<typename... T>
270 constexpr auto front(const HybridTreePath<T...>& tp)
271 -> decltype(treePathEntry<0>(tp))
272 {
273 return treePathEntry<0>(tp);
274 }
275
277
280 template<typename... T>
281 constexpr HybridTreePath<T...,std::size_t> push_back(const HybridTreePath<T...>& tp, std::size_t i)
282 {
283 return HybridTreePath<T...,std::size_t>(std::tuple_cat(tp._data,std::make_tuple(i)));
284 }
285
287
301 template<std::size_t i, typename... T>
302 constexpr HybridTreePath<T...,index_constant<i>> push_back(const HybridTreePath<T...>& tp, index_constant<i> i_ = {})
303 {
304 return HybridTreePath<T...,index_constant<i> >(std::tuple_cat(tp._data,std::make_tuple(i_)));
305 }
306
308
311 template<typename... T>
312 constexpr HybridTreePath<std::size_t,T...> push_front(const HybridTreePath<T...>& tp, std::size_t element)
313 {
314 return HybridTreePath<std::size_t,T...>(std::tuple_cat(std::make_tuple(element),tp._data));
315 }
316
318
332 template<std::size_t i, typename... T>
333 constexpr HybridTreePath<index_constant<i>,T...> push_front(const HybridTreePath<T...>& tp, index_constant<i> _i = {})
334 {
335 return HybridTreePath<index_constant<i>,T...>(std::tuple_cat(std::make_tuple(_i),tp._data));
336 }
337
339
342 template <class... T>
343 constexpr auto pop_front(const HybridTreePath<T...>& tp)
344 {
345 static_assert(sizeof...(T) != 0, "HybridTreePath must not be empty");
346 return unpackIntegerSequence([&](auto... i){
347 return HybridTreePath{std::make_tuple(std::get<i+1>(tp._data)...)};
348 }, std::make_index_sequence<(sizeof...(T) - 1)>{});
349 }
350
352
355 template <class... T>
356 constexpr auto pop_back(const HybridTreePath<T...>& tp)
357 {
358 static_assert(sizeof...(T) != 0, "HybridTreePath must not be empty");
359 return unpackIntegerSequence([&](auto... i){
360 return HybridTreePath{std::make_tuple(std::get<i>(tp._data)...)};
361 }, std::make_index_sequence<(sizeof...(T) - 1)>{});
362 }
363
365
373 template <class... S, class... T>
374 constexpr bool operator==(
375 const HybridTreePath<S...>& lhs,
376 const HybridTreePath<T...>& rhs)
377 {
378 if constexpr (sizeof...(S) == sizeof...(T)) {
379 if constexpr ((Dune::IsInteroperable<S,T>::value &&...)) {
380 return unpackIntegerSequence([&](auto... i){
381 return ((std::get<i>(lhs._data) == std::get<i>(rhs._data)) &&...);
382 }, std::make_index_sequence<(sizeof...(S))>{});
383 } else {
384 return false;
385 }
386 } else {
387 return false;
388 }
389 }
390
392
397 template <class S, S... lhs, class T, T... rhs>
398 constexpr auto operator==(
399 const HybridTreePath<std::integral_constant<S,lhs>...>&,
400 const HybridTreePath<std::integral_constant<T,rhs>...>&)
401 {
402 return std::bool_constant<hybridTreePath(lhs...) == hybridTreePath(rhs...)>{};
403 }
404
405
407 template <class... S, class... T>
408 constexpr auto operator!=(
409 const HybridTreePath<S...>& lhs,
410 const HybridTreePath<T...>& rhs)
411 {
412 return !(lhs == rhs);
413 }
414
416 template <class S, S... lhs, class T, T... rhs>
417 constexpr auto operator!=(
418 const HybridTreePath<std::integral_constant<S,lhs>...>&,
419 const HybridTreePath<std::integral_constant<T,rhs>...>&)
420 {
421 return std::bool_constant<hybridTreePath(lhs...) != hybridTreePath(rhs...)>{};
422 }
423
424 template<std::size_t... i>
425 struct TreePathSize<HybridTreePath<index_constant<i>...> >
426 : public index_constant<sizeof...(i)>
427 {};
428
429
430 template<std::size_t k, std::size_t... i>
431 struct TreePathPushBack<HybridTreePath<index_constant<i>...>,k>
432 {
433 typedef HybridTreePath<index_constant<i>...,index_constant<k>> type;
434 };
435
436 template<std::size_t k, std::size_t... i>
437 struct TreePathPushFront<HybridTreePath<index_constant<i>...>,k>
438 {
439 typedef HybridTreePath<index_constant<k>,index_constant<i>...> type;
440 };
441
442 template<std::size_t k>
443 struct TreePathBack<HybridTreePath<index_constant<k>>>
444 : public index_constant<k>
445 {};
446
447 template<std::size_t j, std::size_t k, std::size_t... l>
448 struct TreePathBack<HybridTreePath<index_constant<j>,index_constant<k>,index_constant<l>...>>
449 : public TreePathBack<HybridTreePath<index_constant<k>,index_constant<l>...>>
450 {};
451
452 template<std::size_t k, std::size_t... i>
453 struct TreePathFront<HybridTreePath<index_constant<k>,index_constant<i>...>>
454 : public index_constant<k>
455 {};
456
457 template<std::size_t k, std::size_t... i>
458 struct TreePathPopBack<HybridTreePath<index_constant<k>>,i...>
459 {
460 typedef HybridTreePath<index_constant<i>...> type;
461 };
462
463 template<std::size_t j,
464 std::size_t k,
465 std::size_t... l,
466 std::size_t... i>
467 struct TreePathPopBack<HybridTreePath<index_constant<j>,index_constant<k>,index_constant<l>...>,i...>
468 : public TreePathPopBack<HybridTreePath<index_constant<k>,index_constant<l>...>,i...,j>
469 {};
470
471 template<std::size_t k, std::size_t... i>
472 struct TreePathPopFront<HybridTreePath<index_constant<k>,index_constant<i>...> >
473 {
474 typedef HybridTreePath<index_constant<i>...> type;
475 };
476
477 template<std::size_t... i, std::size_t... k>
478 struct TreePathConcat<HybridTreePath<index_constant<i>...>,HybridTreePath<index_constant<k>...> >
479 {
480 typedef HybridTreePath<index_constant<i>...,index_constant<k>...> type;
481 };
482
483#ifndef DOXYGEN
484
485 namespace impl {
486
487 // end of recursion
488 template<std::size_t i, typename... T>
489 typename std::enable_if<
490 (i == sizeof...(T))
491 >::type
492 print_hybrid_tree_path(std::ostream& os, const HybridTreePath<T...>& tp, index_constant<i> _i)
493 {}
494
495 // print current entry and recurse
496 template<std::size_t i, typename... T>
497 typename std::enable_if<
498 (i < sizeof...(T))
499 >::type
500 print_hybrid_tree_path(std::ostream& os, const HybridTreePath<T...>& tp, index_constant<i> _i)
501 {
502 os << treePathIndex(tp,_i) << " ";
503 print_hybrid_tree_path(os,tp,index_constant<i+1>{});
504 }
505
506 } // namespace impl
507
508#endif // DOXYGEN
509
511 template<typename... T>
512 std::ostream& operator<<(std::ostream& os, const HybridTreePath<T...>& tp)
513 {
514 os << "HybridTreePath< ";
515 impl::print_hybrid_tree_path(os, tp, index_constant<0>{});
516 os << ">";
517 return os;
518 }
519
520 template<std::size_t... i>
521 using TreePath [[deprecated("use StaticTreePath, this type will be removed after DUNE 2.7")]] = HybridTreePath<Dune::index_constant<i>...>;
522
523 template<std::size_t... i>
524 using StaticTreePath = HybridTreePath<Dune::index_constant<i>...>;
525
527
528 } // namespace TypeTree
529} //namespace Dune
530
531#endif // DUNE_TYPETREE_TREEPATH_HH
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:79
constexpr std::size_t element(std::size_t pos) const
Get the index value at position pos.
Definition: treepath.hh:145
constexpr HybridTreePath(std::tuple< T... > t)
Constructor from a std::tuple
Definition: treepath.hh:97
constexpr HybridTreePath(U... t)
Constructor from arguments.
Definition: treepath.hh:103
constexpr HybridTreePath()
Default constructor.
Definition: treepath.hh:87
static constexpr std::size_t size()
Get the size (length) of this path.
Definition: treepath.hh:114
constexpr auto operator[](Dune::index_constant< i >) const
Get the index value at position pos.
Definition: treepath.hh:121
constexpr auto element(Dune::index_constant< i > pos={}) const
Get the last index value.
Definition: treepath.hh:139
static constexpr index_sequence enumerate()
Returns an index_sequence for enumerating the components of this HybridTreePath.
Definition: treepath.hh:108
constexpr std::size_t operator[](std::size_t pos) const
Get the index value at position pos.
Definition: treepath.hh:127
auto back() const
Get the last index value.
Definition: treepath.hh:156
std::index_sequence_for< T... > index_sequence
An index_sequence for the entries in this HybridTreePath.
Definition: treepath.hh:84
Documentation related stuff.
Traits for type conversions and type information.
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition: indices.hh:125
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:30
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:268
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:237
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
constexpr auto pop_front(const HybridTreePath< T... > &tp)
Removes first index on a HybridTreePath.
Definition: treepath.hh:343
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:257
constexpr std::size_t treePathSize(const HybridTreePath< T... > &)
Returns the size (number of components) of the given HybridTreePath.
Definition: treepath.hh:199
constexpr HybridTreePath< T... > hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:180
constexpr auto front(const HybridTreePath< T... > &tp) -> decltype(treePathEntry< 0 >(tp))
Returns a copy of the first element of the HybridTreePath.
Definition: treepath.hh:270
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:222
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:245
constexpr auto pop_back(const HybridTreePath< T... > &tp)
Removes last index on a HybridTreePath.
Definition: treepath.hh:356
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:191
constexpr HybridTreePath< T..., index_constant< i > > push_back(const HybridTreePath< T... > &tp, index_constant< i > i_={})
Appends a compile time index to a HybridTreePath.
Definition: treepath.hh:302
constexpr HybridTreePath< index_constant< i >, T... > push_front(const HybridTreePath< T... > &tp, index_constant< i > _i={})
Prepends a compile time index to a HybridTreePath.
Definition: treepath.hh:333
Dune namespace.
Definition: alignedallocator.hh:13
Checks whether two types are interoperable.
Definition: typetraits.hh:65
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)