dune-typetree  2.8-git
proxynode.hh
Go to the documentation of this file.
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>
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 
22  template<typename Node>
23  class ProxyNode;
24 
26  template<typename ProxiedNode>
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 
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 
55  template<std::size_t k>
56  struct Child
57  : public ProxiedNode::template Child<k>
58  {};
59 
62 
64 
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 
75 
78  template<std::size_t k>
79  const auto& child (index_constant<k> = {}) const
80  {
81  return node().proxiedNode().template child<k>();
82  }
83 
85 
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 
96 
102  template<std::size_t k>
103  auto childStorage (index_constant<k> = {}) const
104  {
105  return node().proxiedNode().template childStorage<k>();
106  }
107 
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 
123 
128  template<typename ProxiedNode>
130  : public StaticChildAccessors<ProxiedNode>
131  {
132 
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 
153 
155 
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 
166 
169  const auto& child (std::size_t i) const
170  {
171  return node().proxiedNode().child(i);
172  }
173 
175 
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 
186 
192  auto childStorage (std::size_t i) const
193  {
194  return node().proxiedNode().childStorage(i);
195  }
196 
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 
207  template<typename Node, typename NodeTag>
209 
211  template<typename Node>
213  {
214  };
215 
217  template<typename Node>
219  : public StaticChildAccessors<Node>
220  {
221  typedef typename Node::ChildTypes ChildTypes;
222  typedef typename Node::NodeStorage NodeStorage;
223  };
224 
226  template<typename Node>
228  : public DynamicChildAccessors<Node>
229  {
230  typedef typename Node::ChildType ChildType;
231  typedef typename Node::NodeStorage NodeStorage;
232  };
233 
234 
236 
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 
263 
265  static const bool isLeaf = Node::isLeaf;
266 
268  static const bool isPower = Node::isPower;
269 
271  static const bool isComposite = Node::isComposite;
272 
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 
295 
297  template<bool enabled = !proxiedNodeIsConst>
298  typename std::enable_if<enabled,Node&>::type
300  {
301  return *_node;
302  }
303 
305  const Node& proxiedNode () const
306  {
307  return *_node;
308  }
309 
311  template<bool enabled = !proxiedNodeIsConst>
312  typename std::enable_if<enabled,std::shared_ptr<Node> >::type
314  {
315  return _node;
316  }
317 
319  std::shared_ptr<const Node> proxiedNodeStorage () const
320  {
321  return _node;
322  }
323 
325 
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 
338 
339  private:
340 
341  std::shared_ptr<Node> _node;
342  };
343 
345 
346  } // namespace TypeTree
347 } //namespace Dune
348 
349 #endif // DUNE_TYPETREE_PROXYNODE_HH
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:76
typename std::decay_t< Node >::NodeTag NodeTag
Returns the node tag of the given Node.
Definition: nodeinterface.hh:67
decltype(Node::degree()) StaticDegree
Returns the statically known degree of the given Node type as a std::integral_constant.
Definition: nodeinterface.hh:104
Definition: accumulate_static.hh:13
Tag designating a leaf node.
Definition: nodetags.hh:16
Tag designating a power node.
Definition: nodetags.hh:19
Tag designating a composite node.
Definition: nodetags.hh:25
Base class for nodes acting as a proxy for an existing node.
Definition: proxynode.hh:245
ProxyNode(Node &node)
Definition: proxynode.hh:329
const Node & proxiedNode() const
Returns the proxied node (const version).
Definition: proxynode.hh:305
Dune::TypeTree::NodeTag< Node > NodeTag
Definition: proxynode.hh:262
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: proxynode.hh:271
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: proxynode.hh:265
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: proxynode.hh:268
auto degree() const
Definition: proxynode.hh:285
std::enable_if< enabled, Node & >::type proxiedNode()
Returns the proxied node.
Definition: proxynode.hh:299
static const std::size_t CHILDREN
The number of children.
Definition: proxynode.hh:274
Node ProxiedNode
Definition: proxynode.hh:260
std::shared_ptr< const Node > proxiedNodeStorage() const
Returns the storage of the proxied node (const version).
Definition: proxynode.hh:319
static constexpr auto degree()
Definition: proxynode.hh:278
std::enable_if< enabled, std::shared_ptr< Node > >::type proxiedNodeStorage()
Returns the storage of the proxied node.
Definition: proxynode.hh:313
ProxyNode(std::shared_ptr< Node > node)
Definition: proxynode.hh:333
Mixin class providing methods for child access with compile-time parameter.
Definition: proxynode.hh:28
const ProxiedNode::NodeStorage & nodeStorage() const
Definition: proxynode.hh:115
auto & child(index_constant< k >={})
Returns the i-th child.
Definition: proxynode.hh:69
void setChild(ProxyChild &&child, typename std::enable_if< lazy_enabled< k >::value, void * >::type=0)
Sets the i-th child to the passed-in value.
Definition: proxynode.hh:110
const auto & child(index_constant< k >={}) const
Returns the i-th child (const version).
Definition: proxynode.hh:79
auto childStorage(index_constant< k >={})
Returns the storage of the i-th child.
Definition: proxynode.hh:90
auto childStorage(index_constant< k >={}) const
Returns the storage of the i-th child (const version).
Definition: proxynode.hh:103
Access to the type and storage type of the i-th child.
Definition: proxynode.hh:58
Mixin class providing methods for child access with run-time parameter.
Definition: proxynode.hh:131
auto childStorage(std::size_t i) const
Returns the storage of the i-th child (const version).
Definition: proxynode.hh:192
void setChild(std::size_t i, ProxyChild &&child, typename std::enable_if< enabled, void * >::type=0)
Sets the i-th child to the passed-in value.
Definition: proxynode.hh:199
auto & child(std::size_t i)
Returns the i-th child.
Definition: proxynode.hh:160
const auto & child(std::size_t i) const
Returns the i-th child (const version).
Definition: proxynode.hh:169
auto childStorage(std::size_t i)
Returns the storage of the i-th child.
Definition: proxynode.hh:180
Tag-based dispatch to appropriate base class that provides necessary functionality.
Definition: proxynode.hh:208
Node::NodeStorage NodeStorage
Definition: proxynode.hh:222
Node::ChildTypes ChildTypes
Definition: proxynode.hh:221
Node::NodeStorage NodeStorage
Definition: proxynode.hh:231
Node::ChildType ChildType
Definition: proxynode.hh:230