dune-typetree  2.4.0-rc1
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 
50  template<std::size_t k>
51  struct Child {
52 
53  static_assert((k < CHILDREN), "child index out of range");
54 
56  typedef typename std::tuple_element<k,ChildTypes>::type Type;
57 
59  typedef typename std::tuple_element<k,ChildTypes>::type type;
60 
62  typedef typename std::tuple_element<k,NodeStorage>::type Storage;
63 
65  typedef std::shared_ptr<const typename std::tuple_element<k,ChildTypes>::type> ConstStorage;
66  };
67 
70 
72 
75  template<std::size_t k>
77  {
78  return *std::get<k>(_children);
79  }
80 
82 
85  template<std::size_t k>
86  const typename Child<k>::Type& child(index_constant<k> = {}) const
87  {
88  return *std::get<k>(_children);
89  }
90 
92 
95  template<std::size_t k>
97  {
98  return std::get<k>(_children);
99  }
100 
102 
108  template<std::size_t k>
110  {
111  return std::get<k>(_children);
112  }
113 
115  template<std::size_t k>
117  {
118  std::get<k>(_children) = stackobject_to_shared_ptr(child);
119  }
120 
122  template<std::size_t k>
123  void setChild(typename Child<k>::Type&& child, index_constant<k> = {})
124  {
125  std::get<k>(_children) = convert_arg(std::move(child));
126  }
127 
129  template<std::size_t k>
130  void setChild(typename Child<k>::Storage child, index_constant<k> = {})
131  {
132  std::get<k>(_children) = child;
133  }
134 
135  const NodeStorage& nodeStorage() const
136  {
137  return _children;
138  }
139 
141 
144 
145  // The following two methods require a little bit of SFINAE trickery to work correctly:
146  // We have to make sure that they don't shadow the methods for direct child access because
147  // those get called by the generic child() machinery. If that machinery picks up the methods
148  // defined below, we have an infinite recursion.
149  // So the methods make sure that either
150  //
151  // * there are more than one argument. In that case, we got multiple indices and can forward
152  // to the general machine.
153  //
154  // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
155  // The argument thus has to be some kind of TreePath instance that we can also pass to the
156  // generic machine.
157  //
158  // The above SFINAE logic works, but there is still a problem with the return type deduction.
159  // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
160  // type deduction will trigger the infinite recursion.
161 
163 
167 #ifdef DOXYGEN
168  template<typename... Indices>
169  ImplementationDefined& child(Indices... indices)
170 #else
171  template<typename I0, typename... I>
172  auto child(I0 i0, I... i)
173  -> typename std::enable_if<
174  (sizeof...(I) > 0) || !is_flat_index<I0>{},
175  impl::_lazy_member_child_decltype<CompositeNode>
176  >::type::template evaluate<I0,I...>::type
177 #endif
178  {
179  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
180  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
181  );
182  return Dune::TypeTree::child(*this,i0,i...);
183  }
184 
186 
190 #ifdef DOXYGEN
191  template<typename... Indices>
192  const ImplementationDefined& child(Indices... indices)
193 #else
194  template<typename I0, typename... I>
195  auto child(I0 i0, I... i) const
196  -> typename std::enable_if<
197  (sizeof...(I) > 0) || !is_flat_index<I0>{},
198  impl::_lazy_member_child_decltype<const CompositeNode>
199  >::type::template evaluate<I0,I...>::type
200 #endif
201  {
202  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
203  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
204  );
205  return Dune::TypeTree::child(*this,i0,i...);
206  }
207 
209 
210  protected:
211 
214 
216 
224  {}
225 
227  template<typename... Args, typename = typename enable_if<(sizeof...(Args) == CHILDREN)>::type>
228  CompositeNode(Args&&... args)
229  : _children(convert_arg(std::forward<Args>(args))...)
230  {}
231 
233  CompositeNode(std::shared_ptr<Children>... children)
234  : _children(children...)
235  {}
236 
238  CompositeNode(const NodeStorage& children)
239  : _children(children)
240  {}
241 
243 
244  private:
245  NodeStorage _children;
246  };
247 
249 
250  } // namespace TypeTree
251 } //namespace Dune
252 
253 #endif // DUNE_TYPETREE_COMPOSITENODE_HH
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:41
std::shared_ptr< const typename std::tuple_element< k, ChildTypes >::type > ConstStorage
The const storage type of the child.
Definition: compositenode.hh:65
std::tuple_element< k, NodeStorage >::type Storage
The storage type of the child.
Definition: compositenode.hh:62
Definition: accumulate_static.hh:12
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:238
const NodeStorage & nodeStorage() const
Definition: compositenode.hh:135
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:123
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition: compositenode.hh:29
Tag designating a composite node.
Definition: nodetags.hh:22
const ImplementationDefined & child(Indices...indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:192
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:472
STL namespace.
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: utility.hh:312
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the i-th child to the passed-in value.
Definition: compositenode.hh:116
CompositeNode()
Default constructor.
Definition: compositenode.hh:223
CompositeNode(std::shared_ptr< Children >...children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:233
typename impl::_is_flat_index< typename std::decay< T >::type >::type is_flat_index
Type trait that determines whether T is a flat index in the context of child extraction.
Definition: childextraction.hh:627
std::tuple< Children...> ChildTypes
A tuple storing the types of all children.
Definition: compositenode.hh:35
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:23
Access to the type and storage type of the i-th child.
Definition: compositenode.hh:51
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: compositenode.hh:44
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:38
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:32
Child< k >::ConstStorage childStorage(index_constant< k >={}) const
Returns the storage of the i-th child (const version).
Definition: compositenode.hh:109
Child< k >::Type & child(index_constant< k >={})
Returns the i-th child.
Definition: compositenode.hh:76
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:130
CompositeNode(Args &&...args)
Initialize all children with the passed-in objects.
Definition: compositenode.hh:228
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:59
ImplementationDefined & child(Indices...indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:169
static const std::size_t CHILDREN
The number of children.
Definition: compositenode.hh:47
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition: compositenode.hh:53
Child< k >::Storage childStorage(index_constant< k >={})
Returns the storage of the i-th child.
Definition: compositenode.hh:96
const Child< k >::Type & child(index_constant< k >={}) const
Returns the i-th child (const version).
Definition: compositenode.hh:86