4#ifndef DUNE_TYPETREE_TREECONTAINER_HH
5#define DUNE_TYPETREE_TREECONTAINER_HH
12#include <dune/common/indices.hh>
13#include <dune/common/hybridutilities.hh>
17#include <dune/typetree/treepath.hh>
35 template<
class LeafToValue>
36 class ContainerFactory
39 using DynamicDegreeConcept =
decltype((std::size_t(std::declval<N>().
degree()),
true));
42 using StaticDegreeConcept =
decltype((std::integral_constant<std::size_t,
N::degree()>{},
true));
45 using DynamicChildAccessConcept =
decltype((std::declval<N>().child(0u),
true));
56 ContainerFactory(LeafToValue leafToValue) :
57 leafToValue_(leafToValue)
61 auto operator()(
const Node& node)
69 std::enable_if_t<Node::isLeaf, bool> =
true>
72 return leafToValue_(node);
76 StaticDegreeConcept<Node> =
true,
77 DynamicChildAccessConcept<Node> =
true>
81 return std::array{(*this)(node.child(indices))...};
82 }, std::make_index_sequence<std::size_t(Node::degree())>());
86 DynamicDegreeConcept<Node> =
true,
87 DynamicChildAccessConcept<Node> =
true>
90 using TransformedChild =
decltype((*this)(node.child(0)));
91 std::vector<TransformedChild> container;
92 container.reserve(node.degree());
93 for (std::size_t i = 0; i < node.degree(); ++i)
94 container.emplace_back((*
this)(node.child(i)));
99 StaticDegreeConcept<Node> =
true>
103 return Dune::makeTupleVector((*
this)(node.child(indices))...);
104 }, std::make_index_sequence<std::size_t(Node::degree())>());
108 LeafToValue leafToValue_;
115 template<
class Container>
116 class TreeContainerVectorBackend
119 static constexpr decltype(
auto) accessByTreePath(C&& container,
const HybridTreePath<>& path)
124 template<
class C,
class... T>
125 static constexpr decltype(
auto) accessByTreePath(C&& container,
const HybridTreePath<T...>& path)
130 }, std::make_index_sequence<
sizeof...(T)-1>());
131 return accessByTreePath(container[head], tailPath);
134 template<
class C,
class Tree,
135 std::enable_if_t<Tree::isLeaf, bool> =
true>
141 template<
class C,
class Tree,
142 class =
decltype(std::declval<C>().resize(0u))>
145 container.resize(tree.degree());
147 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
151 template<
class C,
class Tree>
155 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
160 using TypeTreeConcept =
decltype((
161 std::declval<T>().degree(),
169 TreeContainerVectorBackend(Container&& container) :
170 container_(
std::move(container))
174 template <
class Tree, TypeTreeConcept<Tree> = true>
175 TreeContainerVectorBackend(
const Tree& tree) :
176 TreeContainerVectorBackend()
182 template <
class C = Container,
183 std::enable_if_t<std::is_default_constructible_v<C>,
bool> =
true>
184 TreeContainerVectorBackend() :
189 decltype(
auto)
operator[](
const HybridTreePath<T...>& path)
const
191 return accessByTreePath(container_, path);
195 decltype(
auto)
operator[](
const HybridTreePath<T...>& path)
197 return accessByTreePath(container_, path);
201 template<
class Tree, TypeTreeConcept<Tree> = true>
202 void resize(
const Tree& tree)
207 const Container& data()
const
218 Container container_;
221 template<
class Container>
222 auto makeTreeContainerVectorBackend(Container&& container)
224 return TreeContainerVectorBackend<std::decay_t<Container>>(std::forward<Container>(container));
234 template<
template<
class Node>
class LeafToValue>
235 struct LeafToDefaultConstructibleValue
238 auto operator()(
const Node& node)
const
240 return LeafToValue<Node>{};
265 template<
class Tree,
class LeafToValue>
268 auto f = std::ref(leafToValue);
269 auto factory = Detail::ContainerFactory<decltype(f)>(f);
270 return Detail::makeTreeContainerVectorBackend(factory(tree));
288 template<
class Value,
class Tree>
297 template<
class Value,
class Tree>
303 template<
template<
class Node>
class LeafToValue,
class Tree>
304 using TreeContainer = std::decay_t<decltype(makeTreeContainer(std::declval<const Tree&>(), std::declval<Detail::LeafToDefaultConstructibleValue<LeafToValue>>()))>;
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:53
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
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:85
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:191
std::decay_t< decltype(makeTreeContainer< Value >(std::declval< const Tree & >()))> UniformTreeContainer
Alias to container type generated by makeTreeContainer for given tree type and uniform value type.
Definition: treecontainer.hh:298
std::decay_t< decltype(makeTreeContainer(std::declval< const Tree & >(), std::declval< Detail::LeafToDefaultConstructibleValue< LeafToValue > >()))> TreeContainer
Alias to container type generated by makeTreeContainer for give tree type and when using LeafToValue ...
Definition: treecontainer.hh:304
auto makeTreeContainer(const Tree &tree)
Create container havin the same structure as the given tree.
Definition: treecontainer.hh:289
Dune namespace.
Definition: alignedallocator.hh:13
Utilities for reduction like operations on ranges.
Helper class for tagging priorities.
Definition: typeutilities.hh:87
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Provides the TupleVector class that augments std::tuple by operator[].