"Fossies" - the Fresh Open Source Software Archive 
Member "dune-typetree-2.8.0/dune/typetree/proxynode.hh" (31 Aug 2021, 9832 Bytes) of package /linux/misc/dune/dune-typetree-2.8.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "proxynode.hh" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.8.0_vs_2.9.0.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3
4 #ifndef DUNE_TYPETREE_PROXYNODE_HH
5 #define DUNE_TYPETREE_PROXYNODE_HH
6
7 #include <type_traits>
8 #include <dune/typetree/nodeinterface.hh>
9 #include <dune/typetree/nodetags.hh>
10 #include <dune/common/shared_ptr.hh>
11 #include <dune/common/indices.hh>
12 #include <dune/common/std/type_traits.hh>
13
14 namespace Dune {
15 namespace TypeTree {
16
17 /** \addtogroup Nodes
18 * \ingroup TypeTree
19 * \{
20 */
21
22 template<typename Node>
23 class ProxyNode;
24
25 //! Mixin class providing methods for child access with compile-time parameter.
26 template<typename ProxiedNode>
27 class StaticChildAccessors
28 {
29
30 static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<ProxiedNode>::type>::value;
31
32 template<std::size_t k>
33 struct lazy_enabled
34 {
35 static const bool value = !proxiedNodeIsConst;
36 };
37
38 typedef ProxyNode<ProxiedNode> Node;
39
40 template<bool enabled = !proxiedNodeIsConst>
41 typename std::enable_if<enabled,Node&>::type
42 node ()
43 {
44 return static_cast<Node&>(*this);
45 }
46
47 const Node& node () const
48 {
49 return static_cast<const Node&>(*this);
50 }
51
52 public:
53
54 //! Access to the type and storage type of the i-th child.
55 template<std::size_t k>
56 struct Child
57 : public ProxiedNode::template Child<k>
58 {};
59
60 //! @name Child Access
61 //! @{
62
63 //! Returns the i-th child.
64 /**
65 * \returns a reference to the i-th child.
66 */
67 template<std::size_t k,
68 typename std::enable_if<lazy_enabled<k>::value, int>::type = 0>
69 auto& child (index_constant<k> = {})
70 {
71 return node().proxiedNode().template child<k>();
72 }
73
74 //! Returns the i-th child (const version).
75 /**
76 * \returns a const reference to the i-th child.
77 */
78 template<std::size_t k>
79 const auto& child (index_constant<k> = {}) const
80 {
81 return node().proxiedNode().template child<k>();
82 }
83
84 //! Returns the storage of the i-th child.
85 /**
86 * \returns a copy of the object storing the i-th child.
87 */
88 template<std::size_t k,
89 typename std::enable_if<lazy_enabled<k>::value, int>::type = 0>
90 auto childStorage (index_constant<k> = {})
91 {
92 return node().proxiedNode().template childStorage<k>();
93 }
94
95 //! Returns the storage of the i-th child (const version).
96 /**
97 * This method is only important if the child is stored as
98 * some kind of pointer, as this allows the pointee type to
99 * become const.
100 * \returns a copy of the object storing the i-th child.
101 */
102 template<std::size_t k>
103 auto childStorage (index_constant<k> = {}) const
104 {
105 return node().proxiedNode().template childStorage<k>();
106 }
107
108 //! Sets the i-th child to the passed-in value.
109 template<std::size_t k, class ProxyChild>
110 void setChild (ProxyChild&& child, typename std::enable_if<lazy_enabled<k>::value,void*>::type = 0)
111 {
112 node().proxiedNode().template setChild<k>(std::forward<ProxyChild>(child));
113 }
114
115 const typename ProxiedNode::NodeStorage& nodeStorage () const
116 {
117 return node().proxiedNode().nodeStorage();
118 }
119
120 };
121
122 //! Mixin class providing methods for child access with run-time parameter.
123 /**
124 * This class also provides the compile-time parameter based methods, as
125 * multiple inheritance from both DynamicChildAccessors and StaticChildAccessors
126 * creates ambigous method lookups.
127 */
128 template<typename ProxiedNode>
129 class DynamicChildAccessors
130 : public StaticChildAccessors<ProxiedNode>
131 {
132
133 typedef ProxyNode<ProxiedNode> Node;
134
135 static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<ProxiedNode>::type>::value;
136
137 template<bool enabled = !proxiedNodeIsConst>
138 typename std::enable_if<enabled,Node&>::type
139 node ()
140 {
141 return static_cast<Node&>(*this);
142 }
143
144 const Node& node () const
145 {
146 return static_cast<const Node&>(*this);
147 }
148
149 public:
150
151 //! @name Child Access (Dynamic methods)
152 //! @{
153
154 //! Returns the i-th child.
155 /**
156 * \returns a reference to the i-th child.
157 */
158 template<bool enabled = !proxiedNodeIsConst,
159 typename std::enable_if<enabled, int>::type = 0>
160 auto& child (std::size_t i)
161 {
162 return node().proxiedNode().child(i);
163 }
164
165 //! Returns the i-th child (const version).
166 /**
167 * \returns a const reference to the i-th child.
168 */
169 const auto& child (std::size_t i) const
170 {
171 return node().proxiedNode().child(i);
172 }
173
174 //! Returns the storage of the i-th child.
175 /**
176 * \returns a copy of the object storing the i-th child.
177 */
178 template<bool enabled = !proxiedNodeIsConst,
179 typename std::enable_if<enabled, int>::type = 0>
180 auto childStorage (std::size_t i)
181 {
182 return node().proxiedNode().childStorage(i);
183 }
184
185 //! Returns the storage of the i-th child (const version).
186 /**
187 * This method is only important if the child is stored as
188 * some kind of pointer, as this allows the pointee type to
189 * become const.
190 * \returns a copy of the object storing the i-th child.
191 */
192 auto childStorage (std::size_t i) const
193 {
194 return node().proxiedNode().childStorage(i);
195 }
196
197 //! Sets the i-th child to the passed-in value.
198 template<class ProxyChild, bool enabled = !proxiedNodeIsConst>
199 void setChild (std::size_t i, ProxyChild&& child, typename std::enable_if<enabled,void*>::type = 0)
200 {
201 node().proxiedNode().setChild(i, std::forward<ProxyChild>(child));
202 }
203
204 };
205
206 //! Tag-based dispatch to appropriate base class that provides necessary functionality.
207 template<typename Node, typename NodeTag>
208 struct ProxyNodeBase;
209
210 //! ProxyNode base class for LeafNode.
211 template<typename Node>
212 struct ProxyNodeBase<Node,LeafNodeTag>
213 {
214 };
215
216 //! ProxyNode base class for CompositeNode.
217 template<typename Node>
218 struct ProxyNodeBase<Node,CompositeNodeTag>
219 : public StaticChildAccessors<Node>
220 {
221 typedef typename Node::ChildTypes ChildTypes;
222 typedef typename Node::NodeStorage NodeStorage;
223 };
224
225 //! ProxyNode base class for PowerNode.
226 template<typename Node>
227 struct ProxyNodeBase<Node,PowerNodeTag>
228 : public DynamicChildAccessors<Node>
229 {
230 typedef typename Node::ChildType ChildType;
231 typedef typename Node::NodeStorage NodeStorage;
232 };
233
234
235 //! Base class for nodes acting as a proxy for an existing node.
236 /**
237 * ProxyNode is a utility class for implementing proxy classes
238 * that need to provide the TypeTree node functionality of the
239 * proxied class. It exactly mirrors the TypeTree node characteristics
240 * of the proxied node.
241 */
242 template<typename Node>
243 class ProxyNode
244 : public ProxyNodeBase<Node,NodeTag<Node>>
245 {
246 static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<Node>::type>::value;
247
248 template <class N>
249 using HasStaticDegree = index_constant<N::degree()>;
250
251 template <class N>
252 static constexpr bool hasStaticDegree = Std::is_detected<HasStaticDegree, N>::value;
253
254 // accessor mixins need to be friends for access to proxiedNode()
255 friend class StaticChildAccessors<Node>;
256 friend class DynamicChildAccessors<Node>;
257
258 public:
259
260 typedef Node ProxiedNode;
261
262 typedef Dune::TypeTree::NodeTag<Node> NodeTag;
263
264 //! Mark this class as non leaf in the \ref TypeTree.
265 static const bool isLeaf = Node::isLeaf;
266
267 //! Mark this class as a non power in the \ref TypeTree.
268 static const bool isPower = Node::isPower;
269
270 //! Mark this class as a composite in the \ref TypeTree.
271 static const bool isComposite = Node::isComposite;
272
273 //! The number of children.
274 static const std::size_t CHILDREN = StaticDegree<Node>::value;
275
276 template <class N = Node,
277 std::enable_if_t<hasStaticDegree<N>, int> = 0>
278 static constexpr auto degree ()
279 {
280 return N::degree();
281 }
282
283 template <class N = Node,
284 std::enable_if_t<not hasStaticDegree<N>, int> = 0>
285 auto degree () const
286 {
287 return proxiedNode().degree();
288 }
289
290
291 protected:
292
293 //! @name Access to the proxied node
294 //! @{
295
296 //! Returns the proxied node.
297 template<bool enabled = !proxiedNodeIsConst>
298 typename std::enable_if<enabled,Node&>::type
299 proxiedNode ()
300 {
301 return *_node;
302 }
303
304 //! Returns the proxied node (const version).
305 const Node& proxiedNode () const
306 {
307 return *_node;
308 }
309
310 //! Returns the storage of the proxied node.
311 template<bool enabled = !proxiedNodeIsConst>
312 typename std::enable_if<enabled,std::shared_ptr<Node> >::type
313 proxiedNodeStorage ()
314 {
315 return _node;
316 }
317
318 //! Returns the storage of the proxied node (const version).
319 std::shared_ptr<const Node> proxiedNodeStorage () const
320 {
321 return _node;
322 }
323
324 //! @}
325
326 //! @name Constructors
327 //! @{
328
329 ProxyNode (Node& node)
330 : _node(stackobject_to_shared_ptr(node))
331 {}
332
333 ProxyNode (std::shared_ptr<Node> node)
334 : _node(std::move(node))
335 {}
336
337 //! @}
338
339 private:
340
341 std::shared_ptr<Node> _node;
342 };
343
344 //! \} group Nodes
345
346 } // namespace TypeTree
347 } //namespace Dune
348
349 #endif // DUNE_TYPETREE_PROXYNODE_HH