DUNE PDELab (2.7)

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
10#include <dune/typetree/nodetags.hh>
11#include <dune/typetree/childextraction.hh>
12#include <dune/typetree/typetraits.hh>
13
14namespace Dune {
15 namespace TypeTree {
16
23 template<typename... Children>
25 {
26
27 public:
28
31
33 typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
34
36 typedef std::tuple<Children...> ChildTypes;
37
39 static const bool isLeaf = false;
40
42 static const bool isPower = false;
43
45 static const bool isComposite = true;
46
48 static const std::size_t CHILDREN = sizeof...(Children);
49
50 static constexpr std::size_t degree()
51 {
52 return sizeof...(Children);
53 }
54
56 template<std::size_t k>
57 struct Child {
58
59 static_assert((k < CHILDREN), "child index out of range");
60
62 typedef typename std::tuple_element<k,ChildTypes>::type Type;
63
65 typedef typename std::tuple_element<k,ChildTypes>::type type;
66
68 typedef typename std::tuple_element<k,NodeStorage>::type Storage;
69
71 typedef std::shared_ptr<const typename std::tuple_element<k,ChildTypes>::type> ConstStorage;
72 };
73
76
78
81 template<std::size_t k>
82 typename Child<k>::Type& child(index_constant<k> = {})
83 {
84 return *std::get<k>(_children);
85 }
86
88
91 template<std::size_t k>
92 const typename Child<k>::Type& child(index_constant<k> = {}) const
93 {
94 return *std::get<k>(_children);
95 }
96
98
101 template<std::size_t k>
102 typename Child<k>::Storage childStorage(index_constant<k> = {})
103 {
104 return std::get<k>(_children);
105 }
106
108
114 template<std::size_t k>
115 typename Child<k>::ConstStorage childStorage(index_constant<k> = {}) const
116 {
117 return std::get<k>(_children);
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) = stackobject_to_shared_ptr(child);
125 }
126
128 template<std::size_t k>
129 void setChild(typename Child<k>::Type&& child, index_constant<k> = {})
130 {
131 std::get<k>(_children) = convert_arg(std::move(child));
132 }
133
135 template<std::size_t k>
136 void setChild(typename Child<k>::Storage child, index_constant<k> = {})
137 {
138 std::get<k>(_children) = child;
139 }
140
141 const NodeStorage& nodeStorage() const
142 {
143 return _children;
144 }
145
147
150
151 // The following two methods require a little bit of SFINAE trickery to work correctly:
152 // We have to make sure that they don't shadow the methods for direct child access because
153 // those get called by the generic child() machinery. If that machinery picks up the methods
154 // defined below, we have an infinite recursion.
155 // So the methods make sure that either
156 //
157 // * there are more than one argument. In that case, we got multiple indices and can forward
158 // to the general machine.
159 //
160 // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
161 // The argument thus has to be some kind of TreePath instance that we can also pass to the
162 // generic machine.
163 //
164 // The above SFINAE logic works, but there is still a problem with the return type deduction.
165 // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
166 // type deduction will trigger the infinite recursion.
167
169
173#ifdef DOXYGEN
174 template<typename... Indices>
176#else
177 template<typename I0, typename... I,
178 std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
179 decltype(auto) child(I0 i0, I... i)
180#endif
181 {
182 static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
183 "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
184 );
185 return Dune::TypeTree::child(*this,i0,i...);
186 }
187
189
193#ifdef DOXYGEN
194 template<typename... Indices>
196#else
197 template<typename I0, typename... I,
198 std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
199 decltype(auto) child(I0 i0, I... i) const
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 std::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
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:25
CompositeNode(Args &&... args)
Initialize all children with the passed-in objects.
Definition: compositenode.hh:228
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:136
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:39
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:175
Child< k >::Storage childStorage(index_constant< k >={})
Returns the storage of the i-th child.
Definition: compositenode.hh:102
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: compositenode.hh:45
static const std::size_t CHILDREN
The number of children.
Definition: compositenode.hh:48
CompositeNode()
Default constructor.
Definition: compositenode.hh:223
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition: compositenode.hh:30
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the i-th child to the passed-in value.
Definition: compositenode.hh:122
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:129
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:233
Child< k >::ConstStorage childStorage(index_constant< k >={}) const
Returns the storage of the i-th child (const version).
Definition: compositenode.hh:115
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition: compositenode.hh:36
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:195
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:42
Child< k >::Type & child(index_constant< k >={})
Returns the i-th child.
Definition: compositenode.hh:82
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:238
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:33
const Child< k >::Type & child(index_constant< k >={}) const
Returns the i-th child (const version).
Definition: compositenode.hh:92
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
Namespace with predefined compile time indices for the range [0,19].
Definition: indices.hh:49
Dune namespace.
Definition: alignedallocator.hh:14
shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:75
STL namespace.
Dummy struct used for documentation purposes.
Definition: documentation.hh:40
Tag designating a composite node.
Definition: nodetags.hh:22
Access to the type and storage type of the i-th child.
Definition: compositenode.hh:57
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition: compositenode.hh:62
std::tuple_element< k, NodeStorage >::type Storage
The storage type of the child.
Definition: compositenode.hh:68
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:65
std::shared_ptr< const typename std::tuple_element< k, ChildTypes >::type > ConstStorage
The const storage type of the child.
Definition: compositenode.hh:71
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 (Jul 15, 22:36, 2024)