DUNE-FUNCTIONS (2.8)

treedata.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_FUNCTIONS_COMMON_TREEDATA_HH
4#define DUNE_FUNCTIONS_COMMON_TREEDATA_HH
5
6#include <memory>
7
8#include <dune/common/shared_ptr.hh>
9
10#include <dune/typetree/pairtraversal.hh>
11
12#include <dune/functions/gridfunctions/gridviewentityset.hh>
13#include <dune/functions/gridfunctions/gridfunction.hh>
14
15namespace Dune {
16namespace Functions {
17
29template<class SimpleNodeVisitorImp, bool leafOnly>
31 public TypeTree::TreeVisitor,
32 public TypeTree::DynamicTraversal
33{
34 // This is only enabled, if we want to incorporate inner nodes.
35 // Checking leafOnly would be sufficient, but for SFINAE the
36 // the enable_if condition must depend on the template parameter.
37 template<typename Node, typename TreePath,
38 typename std::enable_if<(not leafOnly) and (not Node::isLeaf), int>::type = 0>
39 void pre(Node& node, TreePath treePath)
40 {
41 static_cast<SimpleNodeVisitorImp*>(this)->apply(node, treePath);
42 }
43
44 template<typename Node, typename TreePath,
45 typename std::enable_if<(leafOnly) and (not Node::isLeaf), int>::type = 0>
46 void pre(Node& node, TreePath treePath)
47 {}
48
49 template<typename Node, typename TreePath>
50 void leaf(Node& node, TreePath treePath)
51 {
52 static_cast<SimpleNodeVisitorImp*>(this)->apply(node, treePath);
53 }
54};
55
56
57
82template<class T, template<class> class ND, bool LO>
84{
85
86public:
87
89 using Tree = T;
90
92 using size_type = typename Tree::size_type;
93
95 static const bool leafOnly = LO;
96
98 template<class Node>
99 using NodeData = ND<Node>;
100
101protected:
102 using RawContainer = std::vector<void*>;
103
104
105 // Since we can generate the node data type only if
106 // we know the type of the node, we have to do
107 // initialization, copy, and destruction via a
108 // tree traversal. Once we can use C++14 this can
109 // be written in a much easier and more selfcontained
110 // ways using generic lambda functions.
111 // Until then we need explicite visitor classes for
112 // each operation.
113
114 struct InitVisitor :
115 public UniformNodeVisitor<InitVisitor, leafOnly>
116 {
117 InitVisitor(RawContainer& data) :
118 data_(data)
119 {}
120
121 template<typename Node, typename TreePath>
122 void apply(Node& node, TreePath treePath)
123 {
124 auto&& index = node.treeIndex();
125 if (data_.size() < index+1)
126 data_.resize(index+1, nullptr);
127 data_[index] = new NodeData<Node>;
128 }
129
130
131 RawContainer& data_;
132 };
133
134 struct DestroyVisitor :
135 public UniformNodeVisitor<DestroyVisitor, leafOnly>
136 {
137 DestroyVisitor(RawContainer& data) :
138 data_(data)
139 {}
140
141 template<typename Node, typename TreePath>
142 void apply(Node& node, TreePath treePath)
143 {
144 auto&& index = node.treeIndex();
145 auto p = (NodeData<Node>*)(data_[index]);
146 delete p;
147 data_[index] = nullptr;
148 }
149
150 RawContainer& data_;
151 };
152
153 struct CopyVisitor :
154 public UniformNodeVisitor<CopyVisitor, leafOnly>
155 {
156 CopyVisitor(TreeData& thisTD, const TreeData& otherTD) :
157 thisTD_(thisTD),
158 otherTD_(otherTD)
159 {}
160
161 template<typename Node, typename TreePath>
162 void apply(Node& node, TreePath treePath)
163 {
164 thisTD_[node] = otherTD_[node];
165 }
166
167 TreeData& thisTD_;
168 const TreeData& otherTD_;
169 };
170
171public:
172
175 tree_(nullptr)
176 {}
177
185 void init(const Tree& tree)
186 {
187 if (tree_)
188 destroy();
189 tree_ = &tree;
190 TypeTree::applyToTree(*tree_, InitVisitor(data_));
191 }
192
194 TreeData(const TreeData& other) :
195 tree_(other.tree_)
196 {
197 TypeTree::applyToTree(*tree_, InitVisitor(data_));
198 TypeTree::applyToTree(*tree_, CopyVisitor(*this, other));
199 }
200
203 {
204 if (tree_)
205 TypeTree::applyToTree(*tree_, DestroyVisitor(data_));
206 tree_ = other.tree_;
207 TypeTree::applyToTree(*tree_, CopyVisitor(*this, other));
208 return *this;
209 }
210
212 void destroy()
213 {
214 if (tree_)
215 TypeTree::applyToTree(*tree_, DestroyVisitor(data_));
216 tree_ = nullptr;
217 }
218
221 {
222 if (tree_)
223 TypeTree::applyToTree(*tree_, DestroyVisitor(data_));
224 }
225
227 template<class Node>
228 NodeData<Node>& operator[](const Node& node)
229 {
230 return *(NodeData<Node>*)(data_[node.treeIndex()]);
231 }
232
234 template<class Node>
235 const NodeData<Node>& operator[](const Node& node) const
236 {
237 return *(NodeData<Node>*)(data_[node.treeIndex()]);
238 }
239
240protected:
241
242 const Tree* tree_;
243 RawContainer data_;
244};
245
246
247
248} // namespace Functions
249} // namespace Dune
250
251#endif // DUNE_FUNCTIONS_COMMON_TREEDATA_HH
Container allowing to attach data to each node of a tree.
Definition: treedata.hh:84
TreeData(const TreeData &other)
Copy constructor.
Definition: treedata.hh:194
void init(const Tree &tree)
Initialize from tree.
Definition: treedata.hh:185
static const bool leafOnly
Set if data should only be associated to the leafs.
Definition: treedata.hh:95
T Tree
Type of tree the data is associated with.
Definition: treedata.hh:89
void destroy()
Destroy data.
Definition: treedata.hh:212
const NodeData< Node > & operator[](const Node &node) const
Get reference to data associated to given node.
Definition: treedata.hh:235
TreeData & operator=(const TreeData &other)
Copy assignment.
Definition: treedata.hh:202
~TreeData()
Destructor.
Definition: treedata.hh:220
ND< Node > NodeData
Template to determine the data type for given node type.
Definition: treedata.hh:99
TreeData()
Default constructor.
Definition: treedata.hh:174
NodeData< Node > & operator[](const Node &node)
Get mutable reference to data associated to given node.
Definition: treedata.hh:228
typename Tree::size_type size_type
Type used for indices and size information.
Definition: treedata.hh:92
Definition: polynomial.hh:10
Mixin for visitors that should apply the same action on all nodes.
Definition: treedata.hh:33
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)