dune-typetree  3.0-dev
compositenode.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_COMPOSITENODE_HH
5 #define DUNE_TYPETREE_COMPOSITENODE_HH
6 
7 #include <tuple>
8 #include <memory>
9 
12 
13 namespace Dune {
14  namespace TypeTree {
15 
21  template<typename... Children>
24  {
25 
26  public:
27 
30 
32  typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
33 
35  typedef std::tuple<Children...> ChildTypes;
36 
38  static const bool isLeaf = false;
39 
41  static const bool isPower = false;
42 
44  static const bool isComposite = true;
45 
47  static const std::size_t CHILDREN = sizeof...(Children);
48 
49  static constexpr std::size_t degree()
50  {
51  return sizeof...(Children);
52  }
53 
55  template<std::size_t k>
56  struct Child {
57 
58  static_assert((k < CHILDREN), "child index out of range");
59 
61  typedef typename std::tuple_element<k,ChildTypes>::type Type;
62 
64  typedef typename std::tuple_element<k,ChildTypes>::type type;
65 
67  typedef typename std::tuple_element<k,NodeStorage>::type Storage;
68 
70  typedef std::shared_ptr<const typename std::tuple_element<k,ChildTypes>::type> ConstStorage;
71  };
72 
75 
77 
80  template<std::size_t k>
81  typename Child<k>::Type& child(index_constant<k> = {})
82  {
83  return *std::get<k>(_children);
84  }
85 
87 
90  template<std::size_t k>
91  const typename Child<k>::Type& child(index_constant<k> = {}) const
92  {
93  return *std::get<k>(_children);
94  }
95 
97 
100  template<std::size_t k>
101  typename Child<k>::Storage childStorage(index_constant<k> = {})
102  {
103  return std::get<k>(_children);
104  }
105 
107 
113  template<std::size_t k>
114  typename Child<k>::ConstStorage childStorage(index_constant<k> = {}) const
115  {
116  return std::get<k>(_children);
117  }
118 
120  template<std::size_t k>
121  void setChild(typename Child<k>::Type& child, index_constant<k> = {})
122  {
123  std::get<k>(_children) = stackobject_to_shared_ptr(child);
124  }
125 
127  template<std::size_t k>
128  void setChild(typename Child<k>::Type&& child, index_constant<k> = {})
129  {
130  std::get<k>(_children) = convert_arg(std::move(child));
131  }
132 
134  template<std::size_t k>
135  void setChild(typename Child<k>::Storage child, index_constant<k> = {})
136  {
137  std::get<k>(_children) = child;
138  }
139 
140  const NodeStorage& nodeStorage() const
141  {
142  return _children;
143  }
144 
146 
149 
150  // The following two methods require a little bit of SFINAE trickery to work correctly:
151  // We have to make sure that they don't shadow the methods for direct child access because
152  // those get called by the generic child() machinery. If that machinery picks up the methods
153  // defined below, we have an infinite recursion.
154  // So the methods make sure that either
155  //
156  // * there are more than one argument. In that case, we got multiple indices and can forward
157  // to the general machine.
158  //
159  // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
160  // The argument thus has to be some kind of TreePath instance that we can also pass to the
161  // generic machine.
162  //
163  // The above SFINAE logic works, but there is still a problem with the return type deduction.
164  // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
165  // type deduction will trigger the infinite recursion.
166 
168 
172 #ifdef DOXYGEN
173  template<typename... Indices>
174  ImplementationDefined& child(Indices... indices)
175 #else
176  template<typename I0, typename... I>
177  auto child(I0 i0, I... i)
178  -> typename std::enable_if<
179  (sizeof...(I) > 0) || !is_flat_index<I0>{},
180  impl::_lazy_member_child_decltype<CompositeNode>
181  >::type::template evaluate<I0,I...>::type
182 #endif
183  {
184  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
185  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
186  );
187  return Dune::TypeTree::child(*this,i0,i...);
188  }
189 
191 
195 #ifdef DOXYGEN
196  template<typename... Indices>
197  const ImplementationDefined& child(Indices... indices)
198 #else
199  template<typename I0, typename... I>
200  auto child(I0 i0, I... i) const
201  -> typename std::enable_if<
202  (sizeof...(I) > 0) || !is_flat_index<I0>{},
203  impl::_lazy_member_child_decltype<const CompositeNode>
204  >::type::template evaluate<I0,I...>::type
205 #endif
206  {
207  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
208  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
209  );
210  return Dune::TypeTree::child(*this,i0,i...);
211  }
212 
214 
215  protected:
216 
219 
221 
229  {}
230 
232  template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == CHILDREN)>::type>
233  CompositeNode(Args&&... args)
234  : _children(convert_arg(std::forward<Args>(args))...)
235  {}
236 
238  CompositeNode(std::shared_ptr<Children>... children)
239  : _children(children...)
240  {}
241 
243  CompositeNode(const NodeStorage& children)
244  : _children(children)
245  {}
246 
248 
249  private:
250  NodeStorage _children;
251  };
252 
254 
255  } // namespace TypeTree
256 } //namespace Dune
257 
258 #endif // DUNE_TYPETREE_COMPOSITENODE_HH
Dune::TypeTree::CompositeNode::childStorage
Child< k >::ConstStorage childStorage(index_constant< k >={}) const
Returns the storage of the i-th child (const version).
Definition: compositenode.hh:114
nodetags.hh
Dune::TypeTree::CompositeNode::NodeTag
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition: compositenode.hh:29
Dune::TypeTree::CompositeNode
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:23
Dune::TypeTree::CompositeNodeTag
Tag designating a composite node.
Definition: nodetags.hh:22
Dune::TypeTree::CompositeNode::Child::ConstStorage
std::shared_ptr< const typename std::tuple_element< k, ChildTypes >::type > ConstStorage
The const storage type of the child.
Definition: compositenode.hh:70
Dune::TypeTree::CompositeNode::ChildTypes
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition: compositenode.hh:35
Dune::TypeTree::CompositeNode::CHILDREN
static const std::size_t CHILDREN
The number of children.
Definition: compositenode.hh:47
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:243
Dune::TypeTree::CompositeNode::isPower
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:41
childextraction.hh
Dune::TypeTree::child
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:179
Dune::TypeTree::CompositeNode::nodeStorage
const NodeStorage & nodeStorage() const
Definition: compositenode.hh:140
Dune::TypeTree::CompositeNode::childStorage
Child< k >::Storage childStorage(index_constant< k >={})
Returns the storage of the i-th child.
Definition: compositenode.hh:101
Dune::TypeTree::CompositeNode::degree
static constexpr std::size_t degree()
Definition: compositenode.hh:49
Dune
Definition: accumulate_static.hh:13
Dune::TypeTree::CompositeNode::isComposite
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: compositenode.hh:44
Dune::TypeTree::CompositeNode::setChild
void setChild(typename Child< k >::Storage child, index_constant< k >={})
Sets the storage of the i-th child to the passed-in value.
Definition: compositenode.hh:135
Dune::TypeTree::CompositeNode::Child::Type
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition: compositenode.hh:58
Dune::TypeTree::CompositeNode::setChild
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:128
Dune::TypeTree::CompositeNode::child
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:197
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode(Args &&... args)
Initialize all children with the passed-in objects.
Definition: compositenode.hh:233
Dune::TypeTree::CompositeNode::child
Child< k >::Type & child(index_constant< k >={})
Returns the i-th child.
Definition: compositenode.hh:81
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:238
Dune::TypeTree::CompositeNode::child
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:174
Dune::TypeTree::CompositeNode::Child
Access to the type and storage type of the i-th child.
Definition: compositenode.hh:56
Dune::TypeTree::CompositeNode::NodeStorage
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:32
Dune::TypeTree::CompositeNode::Child::type
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:64
Dune::TypeTree::CompositeNode::setChild
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the i-th child to the passed-in value.
Definition: compositenode.hh:121
Dune::TypeTree::CompositeNode::Child::Storage
std::tuple_element< k, NodeStorage >::type Storage
The storage type of the child.
Definition: compositenode.hh:67
Dune::TypeTree::CompositeNode::CompositeNode
CompositeNode()
Default constructor.
Definition: compositenode.hh:228
Dune::TypeTree::CompositeNode::isLeaf
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:38
Dune::TypeTree::is_flat_index
typename impl::_is_flat_index< std::decay_t< T > >::type is_flat_index
Type trait that determines whether T is a flat index in the context of child extraction.
Definition: childextraction.hh:366
Dune::TypeTree::CompositeNode::child
const Child< k >::Type & child(index_constant< k >={}) const
Returns the i-th child (const version).
Definition: compositenode.hh:91