6#ifndef DUNE_TYPETREE_TREECONTAINER_HH
7#define DUNE_TYPETREE_TREECONTAINER_HH
14#include <dune/common/indices.hh>
15#include <dune/common/hybridutilities.hh>
16#include <dune/common/rangeutilities.hh>
17#include <dune/common/tuplevector.hh>
37 template<
class LeafToValue>
41 using DynamicDegreeConcept =
decltype((std::size_t(std::declval<N>().
degree()),
true));
44 using StaticDegreeConcept =
decltype((std::integral_constant<std::size_t, N::degree()>{},
true));
47 using DynamicChildAccessConcept =
decltype((std::declval<N>().child(0u),
true));
59 leafToValue_(leafToValue)
65 return (*
this)(node, Dune::PriorityTag<5>{});
71 std::enable_if_t<Node::isLeaf, bool> =
true>
72 auto operator()(
const Node& node, Dune::PriorityTag<4>)
74 return leafToValue_(node);
78 StaticDegreeConcept<Node> =
true,
79 DynamicChildAccessConcept<Node> =
true>
80 auto operator()(
const Node& node, Dune::PriorityTag<3>)
82 return Dune::unpackIntegerSequence([&](
auto... indices) {
83 return std::array{(*this)(node.child(indices))...};
84 }, std::make_index_sequence<std::size_t(Node::degree())>());
88 DynamicDegreeConcept<Node> =
true,
89 DynamicChildAccessConcept<Node> =
true>
90 auto operator()(
const Node& node, Dune::PriorityTag<2>)
92 using TransformedChild =
decltype((*this)(node.child(0)));
93 std::vector<TransformedChild> container;
94 container.reserve(node.degree());
95 for (std::size_t i = 0; i < node.degree(); ++i)
96 container.emplace_back((*
this)(node.child(i)));
101 StaticDegreeConcept<Node> =
true>
102 auto operator()(
const Node& node, Dune::PriorityTag<1>)
104 return Dune::unpackIntegerSequence([&](
auto... indices) {
105 return Dune::makeTupleVector((*
this)(node.child(indices))...);
106 }, std::make_index_sequence<std::size_t(Node::degree())>());
110 LeafToValue leafToValue_;
117 template<
class Container>
121 static constexpr decltype(
auto) accessByTreePath(C&& container,
const HybridTreePath<>& path)
126 template<
class C,
class... T>
127 static constexpr decltype(
auto) accessByTreePath(C&& container,
const HybridTreePath<T...>& path)
129 auto head = path[Dune::Indices::_0];
130 auto tailPath = Dune::unpackIntegerSequence([&](
auto... i){
131 return treePath(path[Dune::index_constant<i+1>{}]...);
132 }, std::make_index_sequence<
sizeof...(T)-1>());
133 return accessByTreePath(container[head], tailPath);
136 template<
class C,
class Tree,
137 std::enable_if_t<Tree::isLeaf, bool> =
true>
138 static void resizeImpl(C& ,
const Tree& , Dune::PriorityTag<2>)
143 template<
class C,
class Tree,
144 class =
decltype(std::declval<C>().resize(0u))>
145 static void resizeImpl(C& container,
const Tree& tree, Dune::PriorityTag<1>)
147 container.resize(tree.degree());
148 Dune::Hybrid::forEach(Dune::range(tree.degree()), [&](
auto i) {
149 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
153 template<
class C,
class Tree>
154 static void resizeImpl(C& container,
const Tree& tree, Dune::PriorityTag<0>)
156 Dune::Hybrid::forEach(Dune::range(tree.degree()), [&](
auto i) {
157 resizeImpl(container[i], tree.child(i), Dune::PriorityTag<5>{});
162 using TypeTreeConcept =
decltype((
163 std::declval<T>().degree(),
172 container_(std::move(container))
176 template <
class Tree, TypeTreeConcept<Tree> = true>
184 template <
class C = Container,
185 std::enable_if_t<std::is_default_constructible_v<C>,
bool> =
true>
193 return accessByTreePath(container_, path);
199 return accessByTreePath(container_, path);
203 template<
class Tree, TypeTreeConcept<Tree> = true>
206 resizeImpl(container_, tree, Dune::PriorityTag<5>{});
220 Container container_;
223 template<
class Container>
236 template<
template<
class Node>
class LeafToValue>
242 return LeafToValue<Node>{};
267 template<
class Tree,
class LeafToValue>
270 auto f = std::ref(leafToValue);
272 return Detail::makeTreeContainerVectorBackend(factory(tree));
290 template<
class Value,
class Tree>
299 template<
class Value,
class Tree>
305 template<
template<
class Node>
class LeafToValue,
class Tree>
306 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:268
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:300
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:306
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition nodeinterface.hh:79
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition treepath.hh:326
Definition accumulate_static.hh:16
auto makeTreeContainerVectorBackend(Container &&container)
Definition treecontainer.hh:224
Definition treecontainer.hh:39
auto operator()(const Node &node)
Definition treecontainer.hh:63
ContainerFactory(LeafToValue leafToValue)
Create ContainerFactory.
Definition treecontainer.hh:58
Definition treecontainer.hh:119
void resize(const Tree &tree)
Resize the (nested) container depending on the degree of the tree nodes.
Definition treecontainer.hh:204
Container & data()
Definition treecontainer.hh:214
const Container & data() const
Definition treecontainer.hh:209
TreeContainerVectorBackend(Container &&container)
Move the passed container into the internal storage.
Definition treecontainer.hh:171
TreeContainerVectorBackend()
Default constructor. The stored container might need to be resized before usage.
Definition treecontainer.hh:186
TreeContainerVectorBackend(const Tree &tree)
Default construct the container and perform a resize depending on the tree-node degrees.
Definition treecontainer.hh:177
Definition treecontainer.hh:238
auto operator()(const Node &node) const
Definition treecontainer.hh:240
A hybrid version of TreePath that supports both compile time and run time indices.
Definition treepath.hh:158