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
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 [[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>
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
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:168
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
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:122
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:226
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition: compositenode.hh:98
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
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:188
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:108
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition: compositenode.hh:78
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
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition: compositenode.hh:88
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
STL namespace.
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:64
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.111.3 (Jul 15, 22:36, 2024)