Dune Core Modules (2.9.0)

compositenode.hh
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 
11 #include <dune/typetree/nodetags.hh>
12 #include <dune/typetree/childextraction.hh>
13 #include <dune/typetree/typetraits.hh>
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  [[deprecated("Will be removed after release 2.9. Use degree()")]]
50  static const std::size_t CHILDREN = sizeof...(Children);
51 
52  static constexpr auto degree ()
53  {
54  return std::integral_constant<std::size_t,sizeof...(Children)>{};
55  }
56 
58  template<std::size_t k>
59  struct Child {
60 
61  static_assert((k < degree()), "child index out of range");
62 
64  typedef typename std::tuple_element<k,ChildTypes>::type Type;
65 
67  typedef typename std::tuple_element<k,ChildTypes>::type type;
68  };
69 
72 
74 
77  template<std::size_t k>
78  typename Child<k>::Type& child (index_constant<k> = {})
79  {
80  return *std::get<k>(_children);
81  }
82 
84 
87  template<std::size_t k>
88  const typename Child<k>::Type& child (index_constant<k> = {}) const
89  {
90  return *std::get<k>(_children);
91  }
92 
94 
97  template<std::size_t k>
98  std::shared_ptr<typename Child<k>::Type> childStorage (index_constant<k> = {})
99  {
100  return std::get<k>(_children);
101  }
102 
104 
107  template<std::size_t k>
108  std::shared_ptr<const typename Child<k>::Type> childStorage (index_constant<k> = {}) const
109  {
110  return std::get<k>(_children);
111  }
112 
114  template<std::size_t k>
115  void setChild (typename Child<k>::Type& child, index_constant<k> = {})
116  {
117  std::get<k>(_children) = stackobject_to_shared_ptr(child);
118  }
119 
121  template<std::size_t k>
122  void setChild (typename Child<k>::Type&& child, index_constant<k> = {})
123  {
124  std::get<k>(_children) = convert_arg(std::move(child));
125  }
126 
128  template<std::size_t k>
129  void setChild (std::shared_ptr<typename Child<k>::Type> child, index_constant<k> = {})
130  {
131  std::get<k>(_children) = std::move(child);
132  }
133 
134  const NodeStorage& nodeStorage () const
135  {
136  return _children;
137  }
138 
140 
143 
144  // The following two methods require a little bit of SFINAE trickery to work correctly:
145  // We have to make sure that they don't shadow the methods for direct child access because
146  // those get called by the generic child() machinery. If that machinery picks up the methods
147  // defined below, we have an infinite recursion.
148  // So the methods make sure that either
149  //
150  // * there are more than one argument. In that case, we got multiple indices and can forward
151  // to the general machine.
152  //
153  // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
154  // The argument thus has to be some kind of TreePath instance that we can also pass to the
155  // generic machine.
156  //
157  // The above SFINAE logic works, but there is still a problem with the return type deduction.
158  // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
159  // type deduction will trigger the infinite recursion.
160 
162 
166 #ifdef DOXYGEN
167  template<typename... Indices>
169 #else
170  template<typename I0, typename... I,
171  std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
172  decltype(auto) child (I0 i0, I... i)
173 #endif
174  {
175  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
176  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
177  );
178  return Dune::TypeTree::child(*this,i0,i...);
179  }
180 
182 
186 #ifdef DOXYGEN
187  template<typename... Indices>
188  const ImplementationDefined& child (Indices... indices)
189 #else
190  template<typename I0, typename... I,
191  std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
192  decltype(auto) child (I0 i0, I... i) const
193 #endif
194  {
195  static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
196  "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
197  );
198  return Dune::TypeTree::child(*this,i0,i...);
199  }
200 
202 
203  protected:
204 
207 
209 
217  {}
218 
220  template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == degree())>::type>
221  CompositeNode (Args&&... args)
222  : _children(convert_arg(std::forward<Args>(args))...)
223  {}
224 
226  CompositeNode (std::shared_ptr<Children>... children)
227  : _children(std::move(children)...)
228  {}
229 
231  CompositeNode (const NodeStorage& children)
232  : _children(children)
233  {}
234 
236 
237  private:
238  NodeStorage _children;
239  };
240 
242 
243  } // namespace TypeTree
244 } //namespace Dune
245 
246 #endif // DUNE_TYPETREE_COMPOSITENODE_HH
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:26
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:50
CompositeNode()
Default constructor.
Definition: compositenode.hh:216
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:115
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition: compositenode.hh:88
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:122
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:108
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:226
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:129
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition: compositenode.hh:78
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:188
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition: compositenode.hh:98
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:168
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:231
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:34
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:85
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
Namespace with predefined compile time indices for the range [0,19].
Definition: indices.hh:51
Dune namespace.
Definition: alignedallocator.hh:13
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:72
Dummy struct used for documentation purposes.
Definition: documentation.hh:42
Tag designating a composite node.
Definition: nodetags.hh:25
Access to the type and storage type of the i-th child.
Definition: compositenode.hh:59
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition: compositenode.hh:61
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:67
Check if type represents a tree path.
Definition: typetraits.hh:182
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 8, 22:30, 2024)