4#ifndef DUNE_TYPETREE_TREECONTAINER_HH
5#define DUNE_TYPETREE_TREECONTAINER_HH
12#include <dune/common/indices.hh>
13#include <dune/common/hybridutilities.hh>
14#include <dune/common/rangeutilities.hh>
15#include <dune/common/tuplevector.hh>
35 template<
class LeafToValue>
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));
57 leafToValue_(leafToValue)
63 return (*
this)(node, Dune::PriorityTag<5>{});
69 std::enable_if_t<Node::isLeaf, bool> =
true>
70 auto operator()(
const Node& node, Dune::PriorityTag<4>)
72 return leafToValue_(node);
76 StaticDegreeConcept<Node> =
true,
77 DynamicChildAccessConcept<Node> =
true>
78 auto operator()(
const Node& node, Dune::PriorityTag<3>)
80 return Dune::unpackIntegerSequence([&](
auto... indices) {
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>
88 auto operator()(
const Node& node, Dune::PriorityTag<2>)
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>
100 auto operator()(
const Node& node, Dune::PriorityTag<1>)
102 return Dune::unpackIntegerSequence([&](
auto... indices) {
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>
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)
127 auto head = path[Dune::Indices::_0];
128 auto tailPath = Dune::unpackIntegerSequence([&](
auto... i){
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>
136 static void resizeImpl(C& ,
const Tree& , Dune::PriorityTag<2>)
141 template<
class C,
class Tree,
142 class =
decltype(std::declval<C>().resize(0u))>
143 static void resizeImpl(C& container,
const Tree& tree, Dune::PriorityTag<1>)
145 container.resize(tree.degree());
146 Dune::Hybrid::forEach(Dune::range(tree.degree()), [&](
auto i) {
147 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
151 template<
class C,
class Tree>
152 static void resizeImpl(C& container,
const Tree& tree, Dune::PriorityTag<0>)
154 Dune::Hybrid::forEach(Dune::range(tree.degree()), [&](
auto i) {
155 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
160 using TypeTreeConcept =
decltype((
161 std::declval<T>().degree(),
170 container_(std::move(container))
174 template <
class Tree, TypeTreeConcept<Tree> = true>
182 template <
class C = Container,
183 std::enable_if_t<std::is_default_constructible_v<C>,
bool> =
true>
191 return accessByTreePath(container_, path);
197 return accessByTreePath(container_, path);
201 template<
class Tree, TypeTreeConcept<Tree> = true>
204 resizeImpl(container_, tree, Dune::PriorityTag<5>{});
218 Container container_;
221 template<
class Container>
234 template<
template<
class Node>
class LeafToValue>
240 return LeafToValue<Node>{};
265 template<
class Tree,
class LeafToValue>
268 auto f = std::ref(leafToValue);
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>>()))>;
auto makeTreeContainer(const Tree &tree, LeafToValue &&leafToValue)
Create container havin the same structure as the given tree.
Definition: treecontainer.hh:266
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
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:76
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:188
Definition: accumulate_static.hh:13
auto makeTreeContainerVectorBackend(Container &&container)
Definition: treecontainer.hh:222
Definition: treecontainer.hh:37
auto operator()(const Node &node)
Definition: treecontainer.hh:61
ContainerFactory(LeafToValue leafToValue)
Create ContainerFactory.
Definition: treecontainer.hh:56
Definition: treecontainer.hh:117
void resize(const Tree &tree)
Resize the (nested) container depending on the degree of the tree nodes.
Definition: treecontainer.hh:202
Container & data()
Definition: treecontainer.hh:212
const Container & data() const
Definition: treecontainer.hh:207
TreeContainerVectorBackend(Container &&container)
Move the passed container into the internal storage.
Definition: treecontainer.hh:169
TreeContainerVectorBackend()
Default constructor. The stored container might need to be resized before usage.
Definition: treecontainer.hh:184
TreeContainerVectorBackend(const Tree &tree)
Default construct the container and perform a resize depending on the tree-node degrees.
Definition: treecontainer.hh:175
Definition: treecontainer.hh:236
auto operator()(const Node &node) const
Definition: treecontainer.hh:238
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:79