Dune Core Modules (2.8.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
15namespace 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>
97 std::shared_ptr<typename Child<k>::Type> childStorage (index_constant<k> = {})
98 {
99 return std::get<k>(_children);
100 }
101
103
106 template<std::size_t k>
107 std::shared_ptr<const typename Child<k>::Type> childStorage (index_constant<k> = {}) const
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>
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>
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
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
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:40
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:167
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
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:121
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:225
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition: compositenode.hh:97
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
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:187
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:43
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
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition: compositenode.hh:77
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
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition: compositenode.hh:87
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:49
Dune namespace.
Definition: alignedallocator.hh:11
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:70
STL namespace.
Dummy struct used for documentation purposes.
Definition: documentation.hh:40
Tag designating a composite node.
Definition: nodetags.hh:25
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:63
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:66
Check if type represents a tree path.
Definition: typetraits.hh:190
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)