dune-typetree  2.8.0
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 #include <type_traits>
10 
14 
15 namespace Dune {
16  namespace TypeTree {
17 
24  template<typename... Children>
26  {
27 
28  public:
29 
32 
34  typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
35 
37  typedef std::tuple<Children...> ChildTypes;
38 
40  static const bool isLeaf = false;
41 
43  static const bool isPower = false;
44 
46  static const bool isComposite = true;
47 
49  static const std::size_t CHILDREN = sizeof...(Children);
50 
51  static constexpr auto degree ()
52  {
53  return std::integral_constant<std::size_t,sizeof...(Children)>{};
54  }
55 
57  template<std::size_t k>
58  struct Child {
59 
60  static_assert((k < CHILDREN), "child index out of range");
61 
63  typedef typename std::tuple_element<k,ChildTypes>::type Type;
64 
66  typedef typename std::tuple_element<k,ChildTypes>::type type;
67  };
68 
71 
73 
76  template<std::size_t k>
77  typename Child<k>::Type& child (index_constant<k> = {})
78  {
79  return *std::get<k>(_children);
80  }
81 
83 
86  template<std::size_t k>
87  const typename Child<k>::Type& child (index_constant<k> = {}) const
88  {
89  return *std::get<k>(_children);
90  }
91 
93 
96  template<std::size_t k>
98  {
99  return std::get<k>(_children);
100  }
101 
103 
106  template<std::size_t k>
108  {
109  return std::get<k>(_children);
110  }
111 
113  template<std::size_t k>
114  void setChild (typename Child<k>::Type& child, index_constant<k> = {})
115  {
116  std::get<k>(_children) = stackobject_to_shared_ptr(child);
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) = convert_arg(std::move(child));
124  }
125 
127  template<std::size_t k>
128  void setChild (std::shared_ptr<typename Child<k>::Type> child, index_constant<k> = {})
129  {
130  std::get<k>(_children) = std::move(child);
131  }
132 
133  const NodeStorage& nodeStorage () const
134  {
135  return _children;
136  }
137 
139 
142 
143  // The following two methods require a little bit of SFINAE trickery to work correctly:
144  // We have to make sure that they don't shadow the methods for direct child access because
145  // those get called by the generic child() machinery. If that machinery picks up the methods
146  // defined below, we have an infinite recursion.
147  // So the methods make sure that either
148  //
149  // * there are more than one argument. In that case, we got multiple indices and can forward
150  // to the general machine.
151  //
152  // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
153  // The argument thus has to be some kind of TreePath instance that we can also pass to the
154  // generic machine.
155  //
156  // The above SFINAE logic works, but there is still a problem with the return type deduction.
157  // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
158  // type deduction will trigger the infinite recursion.
159 
161 
165 #ifdef DOXYGEN
166  template<typename... Indices>
167  ImplementationDefined& child (Indices... indices)
168 #else
169  template<typename I0, typename... I,
170  std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
171  decltype(auto) child (I0 i0, I... i)
172 #endif
173  {
174  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
175  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
176  );
177  return Dune::TypeTree::child(*this,i0,i...);
178  }
179 
181 
185 #ifdef DOXYGEN
186  template<typename... Indices>
187  const ImplementationDefined& child (Indices... indices)
188 #else
189  template<typename I0, typename... I,
190  std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
191  decltype(auto) child (I0 i0, I... i) const
192 #endif
193  {
194  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
195  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
196  );
197  return Dune::TypeTree::child(*this,i0,i...);
198  }
199 
201 
202  protected:
203 
206 
208 
216  {}
217 
219  template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == CHILDREN)>::type>
220  CompositeNode (Args&&... args)
221  : _children(convert_arg(std::forward<Args>(args))...)
222  {}
223 
225  CompositeNode (std::shared_ptr<Children>... children)
226  : _children(std::move(children)...)
227  {}
228 
230  CompositeNode (const NodeStorage& children)
231  : _children(children)
232  {}
233 
235 
236  private:
237  NodeStorage _children;
238  };
239 
241 
242  } // namespace TypeTree
243 } //namespace Dune
244 
245 #endif // DUNE_TYPETREE_COMPOSITENODE_HH
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:126
Definition: accumulate_static.hh:13
Type
Definition: treepath.hh:30
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:26
CompositeNode(Args &&... args)
Initialize all children with the passed-in objects.
Definition: compositenode.hh:220
const NodeStorage & nodeStorage() const
Definition: compositenode.hh:133
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:40
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: compositenode.hh:46
static const std::size_t CHILDREN
The number of children.
Definition: compositenode.hh:49
CompositeNode()
Default constructor.
Definition: compositenode.hh:215
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition: compositenode.hh:31
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the k-th child to the passed-in value.
Definition: compositenode.hh:114
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition: compositenode.hh:87
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:121
std::shared_ptr< const typename Child< k >::Type > childStorage(index_constant< k >={}) const
Returns the storage of the k-th child (const version).
Definition: compositenode.hh:107
static constexpr auto degree()
Definition: compositenode.hh:51
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:225
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition: compositenode.hh:37
void setChild(std::shared_ptr< typename Child< k >::Type > child, index_constant< k >={})
Sets the storage of the k-th child to the passed-in value.
Definition: compositenode.hh:128
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition: compositenode.hh:77
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:43
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:187
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition: compositenode.hh:97
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:167
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:230
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:34
Access to the type and storage type of the i-th child.
Definition: compositenode.hh:58
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition: compositenode.hh:60
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:66
Tag designating a composite node.
Definition: nodetags.hh:25
Check if type represents a tree path.
Definition: typetraits.hh:190