DUNE PDELab (git)

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// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-PDELab-exception
5
6#ifndef DUNE_TYPETREE_COMPOSITENODE_HH
7#define DUNE_TYPETREE_COMPOSITENODE_HH
8
9#include <tuple>
10#include <memory>
11#include <type_traits>
12
13#include <dune/typetree/nodetags.hh>
14#include <dune/typetree/childextraction.hh>
15#include <dune/typetree/typetraits.hh>
16
17namespace Dune {
18 namespace TypeTree {
19
26 template<typename... Children>
28 {
29
30 public:
31
34
36 typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
37
39 typedef std::tuple<Children...> ChildTypes;
40
42 static const bool isLeaf = false;
43
45 static const bool isPower = false;
46
48 static const bool isComposite = true;
49
50 static constexpr auto degree ()
51 {
52 return std::integral_constant<std::size_t,sizeof...(Children)>{};
53 }
54
56 template<std::size_t k>
57 struct Child {
58
59 static_assert((k < degree()), "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 };
67
70
72
75 template<std::size_t k>
76 typename Child<k>::Type& child (index_constant<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>
96 std::shared_ptr<typename Child<k>::Type> childStorage (index_constant<k> = {})
97 {
98 return std::get<k>(_children);
99 }
100
102
105 template<std::size_t k>
106 std::shared_ptr<const typename Child<k>::Type> childStorage (index_constant<k> = {}) const
107 {
108 return std::get<k>(_children);
109 }
110
112 template<std::size_t k>
113 void setChild (typename Child<k>::Type& child, index_constant<k> = {})
114 {
115 std::get<k>(_children) = stackobject_to_shared_ptr(child);
116 }
117
119 template<std::size_t k>
120 void setChild (typename Child<k>::Type&& child, index_constant<k> = {})
121 {
122 std::get<k>(_children) = convert_arg(std::move(child));
123 }
124
126 template<std::size_t k>
127 void setChild (std::shared_ptr<typename Child<k>::Type> child, index_constant<k> = {})
128 {
129 std::get<k>(_children) = std::move(child);
130 }
131
132 const NodeStorage& nodeStorage () const
133 {
134 return _children;
135 }
136
138
141
142 // The following two methods require a little bit of SFINAE trickery to work correctly:
143 // We have to make sure that they don't shadow the methods for direct child access because
144 // those get called by the generic child() machinery. If that machinery picks up the methods
145 // defined below, we have an infinite recursion.
146 // So the methods make sure that either
147 //
148 // * there are more than one argument. In that case, we got multiple indices and can forward
149 // to the general machine.
150 //
151 // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
152 // The argument thus has to be some kind of TreePath instance that we can also pass to the
153 // generic machine.
154 //
155 // The above SFINAE logic works, but there is still a problem with the return type deduction.
156 // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
157 // type deduction will trigger the infinite recursion.
158
160
164#ifdef DOXYGEN
165 template<typename... Indices>
167#else
168 template<typename I0, typename... I,
169 std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
170 decltype(auto) child (I0 i0, I... i)
171#endif
172 {
173 static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
174 "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
175 );
176 return Dune::TypeTree::child(*this,i0,i...);
177 }
178
180
184#ifdef DOXYGEN
185 template<typename... Indices>
187#else
188 template<typename I0, typename... I,
189 std::enable_if_t<(sizeof...(I) > 0) || IsTreePath<I0>::value, int > = 0>
190 decltype(auto) child (I0 i0, I... i) const
191#endif
192 {
193 static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
194 "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
195 );
196 return Dune::TypeTree::child(*this,i0,i...);
197 }
198
200
201 protected:
202
205
207
215 {}
216
218 template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == degree())>::type>
219 CompositeNode (Args&&... args)
220 : _children(convert_arg(std::forward<Args>(args))...)
221 {}
222
224 CompositeNode (std::shared_ptr<Children>... children)
225 : _children(std::move(children)...)
226 {}
227
229 CompositeNode (const NodeStorage& children)
230 : _children(children)
231 {}
232
234
235 private:
236 NodeStorage _children;
237 };
238
240
241 } // namespace TypeTree
242} //namespace Dune
243
244#endif // DUNE_TYPETREE_COMPOSITENODE_HH
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:28
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition: compositenode.hh:42
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:166
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition: compositenode.hh:48
CompositeNode()
Default constructor.
Definition: compositenode.hh:214
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition: compositenode.hh:33
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the k-th child to the passed-in value.
Definition: compositenode.hh:113
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition: compositenode.hh:120
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition: compositenode.hh:224
std::shared_ptr< typename Child< k >::Type > childStorage(index_constant< k >={})
Returns the storage of the k-th child.
Definition: compositenode.hh:96
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition: compositenode.hh:39
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:127
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition: compositenode.hh:186
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition: compositenode.hh:45
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:106
Child< k >::Type & child(index_constant< k >={})
Returns the k-th child.
Definition: compositenode.hh:76
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition: compositenode.hh:229
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:36
const Child< k >::Type & child(index_constant< k >={}) const
Returns the k-th child (const version).
Definition: compositenode.hh:86
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
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:128
Namespace with predefined compile time indices for the range [0,19].
Definition: indices.hh:50
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:27
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, ChildTypes >::type type
The type of the child.
Definition: compositenode.hh:65
Check if type represents a tree path.
Definition: typetraits.hh:184
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 12, 23:30, 2024)