6#ifndef DUNE_TYPETREE_TREEPATH_HH
7#define DUNE_TYPETREE_TREEPATH_HH
14#include <dune/common/documentation.hh>
15#include <dune/common/version.hh>
16#include <dune/common/typetraits.hh>
17#include <dune/common/indices.hh>
18#include <dune/common/hybridutilities.hh>
19#include <dune/common/typelist.hh>
30 struct check_size_t_impl
32 static constexpr auto check() {
33 return std::is_same_v<T, std::size_t>;
37 template<
class T, T v>
38 struct check_size_t_impl<std::integral_constant<T,v>>
40 static constexpr auto check() {
41 return std::is_same_v<T, std::size_t>;
46 constexpr auto check_size_t() {
47 return check_size_t_impl<T>::check();
51 constexpr auto cast_size_t(
const T & v) {
54 std::is_convertible_v<T,std::size_t> &&
55 std::is_integral_v<T>,
56 "HybridTreePath indices must be convertible to std::size_t or std::integral_constant<std::size_t,v>");
59 "HybridTreePath indices must be convertible to std::size_t or std::integral_constant<std::size_t,v>");
60 return std::size_t(v);
63 template<
class T, T v>
64 constexpr auto cast_size_t(std::integral_constant<T,v>) {
68 std::is_convertible_v<T,std::size_t> &&
69 std::is_integral_v<T> &&
71 "HybridTreePath indices must be convertible to std::size_t or std::integral_constant<std::size_t,v>");
72 return std::integral_constant<std::size_t,v>();
77 [[deprecated(
"HybridTreePath index storage should be std::size_t or std::integral_constant<std::size_t,v>!\n"
78 "Using anything else is deprecated and will not possible after the 2.10 release.\n"
79 "It is adviced not to specify the template parameters expicitly,\n"
80 "but to use the helper functions `hybridTreePath` or `treePath`."
81 "These take care of converting indices to the appropriate storage.")]]
82 constexpr bool check_storage_type(MetaType<T>) {
87 template<std::
size_t v>
88 constexpr bool check_storage_type(MetaType<std::integral_constant<std::size_t,v>>) {
93 constexpr bool check_storage_type(MetaType<std::size_t>) {
98 template<
typename... T>
105 namespace TreePathType {
112 template<
typename,std::
size_t>
115 template<
typename,std::
size_t>
124 template<
typename, std::size_t...>
130 template<
typename,
typename>
133 template<std::size_t... i>
137 template<std::size_t k, std::size_t... i>
156 template<
typename... T>
161#if DUNE_VERSION_GTE(TYPETREE,2,10)
163 static_assert((... && Impl::check_size_t<T>()),
164 "HybridTreePath index storage must be std::size_t or std::integral_constant<std::size_t,v>");
175 [[maybe_unused]]
constexpr bool check =
176 (... && Impl::check_storage_type(MetaType<T>()) );
189 [[maybe_unused]]
constexpr bool check =
190 (... && Impl::check_storage_type(MetaType<T>()) );
194 template<
typename... U,
195 typename std::enable_if_t<(
sizeof...(T) > 0 &&
sizeof...(U) ==
sizeof...(T)),
bool> =
true>
199 [[maybe_unused]]
constexpr bool check =
200 (... && Impl::check_storage_type(MetaType<T>()) );
210 [[nodiscard]]
constexpr static std::size_t
size()
216 [[nodiscard]]
constexpr static std::size_t
max_size()
222 template<std::size_t i,
223 std::enable_if_t<(
sizeof...(T) > i),
bool> =
true>
224 [[nodiscard]]
constexpr auto operator[](Dune::index_constant<i>)
const
226 return std::get<i>(_data);
230 [[nodiscard]]
constexpr std::size_t
operator[](std::size_t pos)
const
232 std::size_t entry = 0;
233 Dune::Hybrid::forEach(
enumerate(), [&] (
auto i) {
241 template<std::size_t i,
242 std::enable_if_t<(
sizeof...(T) > i),
bool> =
true>
243 [[nodiscard]]
constexpr auto element(Dune::index_constant<i> pos = {})
const
245 return std::get<i>(_data);
249 [[nodiscard]]
constexpr std::size_t
element(std::size_t pos)
const
251 std::size_t entry = 0;
252 Dune::Hybrid::forEach(
enumerate(), [&] (
auto i) {
260 template<std::size_t n =
sizeof...(T),
261 std::enable_if_t<(n > 0 && n ==
sizeof...(T)),
bool> =
true>
262 [[nodiscard]]
constexpr auto front()
const
264 return std::get<0>(_data);
268 template<std::size_t n =
sizeof...(T),
269 std::enable_if_t<(n > 0 && n ==
sizeof...(T)),
bool> =
true>
270 [[nodiscard]]
constexpr auto back()
const
272 return std::get<n-1>(_data);
280 using Data = std::tuple<T...>;
294 template<
typename... T>
298 static_assert((... && Impl::check_size_t<T>()),
299 "HybridTreePath indices must be of type std::size_t or std::integral_constant<std::size_t,v>");
311 template<
typename... T>
325 template<
typename... T>
326 [[nodiscard]]
constexpr auto treePath(
const T&... t)
333 template<
typename... T>
356 template<std::size_t i,
typename... T>
358 ->
typename std::decay<
decltype(std::get<i>(tp._data))>::type
360 return std::get<i>(tp._data);
379 template<std::size_t i,
typename... T>
382 return std::get<i>(tp._data);
391 template<
typename... T>
393 ->
decltype(tp.
back())
404 template<
typename... T>
406 ->
decltype(tp.
front())
415 template<
typename... T>
418 return HybridTreePath<T...,std::size_t>(std::tuple_cat(tp._data,std::make_tuple(i)));
436 template<std::size_t i,
typename... T>
439 return HybridTreePath<T...,index_constant<i> >(std::tuple_cat(tp._data,std::make_tuple(i_)));
446 template<
typename... T>
449 return HybridTreePath<std::size_t,T...>(std::tuple_cat(std::make_tuple(element),tp._data));
467 template<std::size_t i,
typename... T>
470 return HybridTreePath<index_constant<i>,T...>(std::tuple_cat(std::make_tuple(_i),tp._data));
485 template<
typename I,
typename... T, std::enable_if_t<(
sizeof...(T) > 0),
bool> =
true>
487 using ::Dune::Hybrid::plus;
504 template<
typename I,
typename... T, std::enable_if_t<(
sizeof...(T) > 0),
bool> =
true>
506 using ::Dune::Hybrid::plus;
511 template<
class... Head,
class... Other>
519 constexpr std::size_t size =
sizeof...(T);
520 return unpackIntegerSequence([&](
auto... i){
521 return treePath(tp[index_constant<size-i-1>{}] ...);
522 }, std::make_index_sequence<size>{});
529 template <
class... T, std::enable_if_t<(
sizeof...(T) > 0),
bool> =
true>
532 return unpackIntegerSequence([&](
auto... i){
533 return HybridTreePath{std::make_tuple(std::get<i+1>(tp._data)...)};
534 }, std::make_index_sequence<(
sizeof...(T) - 1)>{});
541 template <
class... T, std::enable_if_t<(
sizeof...(T) > 0),
bool> =
true>
544 return unpackIntegerSequence([&](
auto... i){
546 }, std::make_index_sequence<(
sizeof...(T) - 1)>{});
558 template <
class... S,
class... T>
563 if constexpr (
sizeof...(S) ==
sizeof...(T)) {
564 if constexpr ((Dune::IsInteroperable<S,T>::value &&...)) {
565 return unpackIntegerSequence([&](
auto... i){
566 return ((std::get<i>(lhs._data) == std::get<i>(rhs._data)) &&...);
567 }, std::make_index_sequence<(
sizeof...(S))>{});
582 template <
class S, S... lhs,
class T, T... rhs>
592 template <
class... S,
class... T>
597 return !(lhs == rhs);
601 template <
class S, S... lhs,
class T, T... rhs>
610 inline namespace Literals {
617 template <
char... digits>
618 constexpr auto operator"" _tp()
620 using namespace Dune::Indices::Literals;
627 template<std::size_t... i>
629 :
public index_constant<sizeof...(i)>
633 template<std::size_t k, std::size_t... i>
639 template<std::size_t k, std::size_t... i>
645 template<std::
size_t k>
647 :
public index_constant<k>
650 template<std::size_t j, std::size_t k, std::size_t... l>
652 :
public TreePathBack<HybridTreePath<index_constant<k>,index_constant<l>...>>
655 template<std::size_t k, std::size_t... i>
657 :
public index_constant<k>
660 template<std::size_t k, std::size_t... i>
666 template<std::size_t j,
671 :
public TreePathPopBack<HybridTreePath<index_constant<k>,index_constant<l>...>,i...,j>
674 template<std::size_t k, std::size_t... i>
680 template<std::size_t... i, std::size_t... k>
691 template<std::size_t i,
typename... T>
692 typename std::enable_if<
699 template<std::size_t i,
typename... T>
700 typename std::enable_if<
703 print_hybrid_tree_path(std::ostream& os,
const HybridTreePath<T...>& tp, index_constant<i> _i)
706 print_hybrid_tree_path(os,tp,index_constant<i+1>{});
714 template<
typename... T>
717 os <<
"HybridTreePath< ";
718 impl::print_hybrid_tree_path(os, tp, index_constant<0>{});
723 template<std::size_t... i>
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:416
std::ostream & operator<<(std::ostream &os, const HybridTreePath< T... > &tp)
Dumps a HybridTreePath to a stream.
Definition treepath.hh:715
constexpr std::size_t treePathSize(const HybridTreePath< T... > &)
Returns the size (number of components) of the given HybridTreePath.
Definition treepath.hh:334
constexpr auto back(const HybridTreePath< T... > &tp) -> decltype(tp.back())
Returns a copy of the last element of the HybridTreePath.
Definition treepath.hh:392
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:447
constexpr auto accumulate_front(const HybridTreePath< T... > &tp, I i)
Hybrid utility that accumulates to the front of a multi-index.
Definition treepath.hh:505
constexpr auto pop_front(const HybridTreePath< T... > &tp)
Removes first index on a HybridTreePath.
Definition treepath.hh:530
constexpr auto reverse(const HybridTreePath< T... > &tp)
Reverses the order of the elements in the path.
Definition treepath.hh:518
constexpr auto accumulate_back(const HybridTreePath< T... > &tp, I i)
Hybrid utility that accumulates to the back of a multi-index.
Definition treepath.hh:486
constexpr auto join(const HybridTreePath< Head... > &head, const Other &... tail)
Join two tree paths into one.
Definition treepath.hh:512
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:357
constexpr auto pop_back(const HybridTreePath< T... > &tp)
Removes last index on a HybridTreePath.
Definition treepath.hh:542
constexpr auto operator!=(const HybridTreePath< S... > &lhs, const HybridTreePath< T... > &rhs)
Compare two HybridTreePaths for unequality.
Definition treepath.hh:593
constexpr auto hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition treepath.hh:312
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:380
constexpr auto makeTreePath(const T... t)
helper function to construct a new HybridTreePath from the given indices.
Definition treepath.hh:295
constexpr bool operator==(const HybridTreePath< S... > &lhs, const HybridTreePath< T... > &rhs)
Compare two HybridTreePaths for value equality.
Definition treepath.hh:559
void print_tree_path(std::ostream &os)
Definition treepath.hh:134
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition treepath.hh:326
constexpr auto front(const HybridTreePath< T... > &tp) -> decltype(tp.front())
Returns a copy of the first element of the HybridTreePath.
Definition treepath.hh:405
Definition accumulate_static.hh:16
Type
Definition treepath.hh:106
@ fullyStatic
Definition treepath.hh:106
@ dynamic
Definition treepath.hh:106
Statically combine two values of type result_type using +.
Definition accumulate_static.hh:49
A hybrid version of TreePath that supports both compile time and run time indices.
Definition treepath.hh:158
constexpr HybridTreePath(HybridTreePath &&tp)=default
constexpr auto back() const
Get the last index value. Only available in non-empty paths.
Definition treepath.hh:270
constexpr HybridTreePath & operator=(const HybridTreePath &tp)=default
constexpr std::size_t element(std::size_t pos) const
Get the index value at position pos.
Definition treepath.hh:249
constexpr HybridTreePath(std::tuple< T... > t)
Constructor from a std::tuple
Definition treepath.hh:186
constexpr HybridTreePath & operator=(HybridTreePath &&tp)=default
constexpr HybridTreePath(U... t)
Constructor from arguments.
Definition treepath.hh:196
constexpr HybridTreePath()
Default constructor.
Definition treepath.hh:173
constexpr auto element(Dune::index_constant< i > pos={}) const
Get the last index value.
Definition treepath.hh:243
static constexpr std::size_t size()
Get the size (length) of this path.
Definition treepath.hh:210
constexpr auto operator[](Dune::index_constant< i >) const
Get the index value at position pos.
Definition treepath.hh:224
constexpr auto front() const
Get the first index value. Only available in non-empty paths.
Definition treepath.hh:262
static constexpr index_sequence enumerate()
Returns an index_sequence for enumerating the components of this HybridTreePath.
Definition treepath.hh:204
constexpr HybridTreePath(const HybridTreePath &tp)=default
constexpr std::size_t operator[](std::size_t pos) const
Get the index value at position pos.
Definition treepath.hh:230
static constexpr std::size_t max_size()
Get the size (length) of this path.
Definition treepath.hh:216
std::index_sequence_for< T... > index_sequence
An index_sequence for the entries in this HybridTreePath.
Definition treepath.hh:170
Definition treepath.hh:110
Definition treepath.hh:113
Definition treepath.hh:116
Definition treepath.hh:119
Definition treepath.hh:122
Definition treepath.hh:125
Definition treepath.hh:128
Definition treepath.hh:131
HybridTreePath< index_constant< i >..., index_constant< k > > type
Definition treepath.hh:636
HybridTreePath< index_constant< k >, index_constant< i >... > type
Definition treepath.hh:642
HybridTreePath< index_constant< i >... > type
Definition treepath.hh:663
HybridTreePath< index_constant< i >... > type
Definition treepath.hh:677
HybridTreePath< index_constant< i >..., index_constant< k >... > type
Definition treepath.hh:683