dune-typetree 3.0-dev
compositenode.hh
Go to the documentation of this file.
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
12
13namespace Dune {
14 namespace TypeTree {
15
22 template<typename... Children>
24 {
25
26 public:
27
30
32 typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
33
35 typedef std::tuple<Children...> ChildTypes;
36
38 static const bool isLeaf = false;
39
41 static const bool isPower = false;
42
44 static const bool isComposite = true;
45
47 static const std::size_t CHILDREN = sizeof...(Children);
48
49 static constexpr std::size_t degree()
50 {
51 return sizeof...(Children);
52 }
53
55 template<std::size_t k>
56 struct Child {
57
58 static_assert((k < CHILDREN), "child index out of range");
59
61 typedef typename std::tuple_element<k,ChildTypes>::type Type;
62
64 typedef typename std::tuple_element<k,ChildTypes>::type type;
65
67 typedef typename std::tuple_element<k,NodeStorage>::type Storage;
68
70 typedef std::shared_ptr<const typename std::tuple_element<k,ChildTypes>::type> ConstStorage;
71 };
72
75
77
80 template<std::size_t k>
81 typename Child<k>::Type& child(index_constant<k> = {})
82 {
83 return *std::get<k>(_children);
84 }
85
87
90 template<std::size_t k>
91 const typename Child<k>::Type& child(index_constant<k> = {}) const
92 {
93 return *std::get<k>(_children);
94 }
95
97
100 template<std::size_t k>
101 typename Child<k>::Storage childStorage(index_constant<k> = {})
102 {
103 return std::get<k>(_children);
104 }
105
107
113 template<std::size_t k>
114 typename Child<k>::ConstStorage childStorage(index_constant<k> = {}) const
115 {
116 return std::get<k>(_children);
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) = stackobject_to_shared_ptr(child);
124 }
125
127 template<std::size_t k>
128 void setChild(typename Child<k>::Type&& child, index_constant<k> = {})
129 {
130 std::get<k>(_children) = convert_arg(std::move(child));
131 }
132
134 template<std::size_t k>
135 void setChild(typename Child<k>::Storage child, index_constant<k> = {})
136 {
137 std::get<k>(_children) = child;
138 }
139
141 {
142 return _children;
143 }
144
146
149
150 // The following two methods require a little bit of SFINAE trickery to work correctly:
151 // We have to make sure that they don't shadow the methods for direct child access because
152 // those get called by the generic child() machinery. If that machinery picks up the methods
153 // defined below, we have an infinite recursion.
154 // So the methods make sure that either
155 //
156 // * there are more than one argument. In that case, we got multiple indices and can forward
157 // to the general machine.
158 //
159 // * the first argument is not a valid flat index, i.e. either a std::size_t or an index_constant.
160 // The argument thus has to be some kind of TreePath instance that we can also pass to the
161 // generic machine.
162 //
163 // The above SFINAE logic works, but there is still a problem with the return type deduction.
164 // We have to do a lazy lookup of the return type after SFINAE has succeeded, otherwise the return
165 // type deduction will trigger the infinite recursion.
166
168
172#ifdef DOXYGEN
173 template<typename... Indices>
174 ImplementationDefined& child(Indices... indices)
175#else
176 template<typename I0, typename... I>
177 auto child(I0 i0, I... i)
178 -> typename std::enable_if<
179 (sizeof...(I) > 0) || !is_flat_index<I0>{},
180 impl::_lazy_member_child_decltype<CompositeNode>
181 >::type::template evaluate<I0,I...>::type
182#endif
183 {
184 static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
185 "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
186 );
187 return Dune::TypeTree::child(*this,i0,i...);
188 }
189
191
195#ifdef DOXYGEN
196 template<typename... Indices>
197 const ImplementationDefined& child(Indices... indices)
198#else
199 template<typename I0, typename... I>
200 auto child(I0 i0, I... i) const
201 -> typename std::enable_if<
202 (sizeof...(I) > 0) || !is_flat_index<I0>{},
203 impl::_lazy_member_child_decltype<const CompositeNode>
204 >::type::template evaluate<I0,I...>::type
205#endif
206 {
207 static_assert(sizeof...(I) > 0 || impl::_non_empty_tree_path(I0{}),
208 "You cannot use the member function child() with an empty TreePath, use the freestanding version child(node,treePath) instead."
209 );
210 return Dune::TypeTree::child(*this,i0,i...);
211 }
212
214
215 protected:
216
219
221
230
232 template<typename... Args, typename = typename std::enable_if<(sizeof...(Args) == CHILDREN)>::type>
233 CompositeNode(Args&&... args)
234 : _children(convert_arg(std::forward<Args>(args))...)
235 {}
236
238 CompositeNode(std::shared_ptr<Children>... children)
239 : _children(children...)
240 {}
241
243 CompositeNode(const NodeStorage& children)
244 : _children(children)
245 {}
246
248
249 private:
250 NodeStorage _children;
251 };
252
254
255 } // namespace TypeTree
256} //namespace Dune
257
258#endif // DUNE_TYPETREE_COMPOSITENODE_HH
typename impl::_is_flat_index< std::decay_t< T > >::type is_flat_index
Type trait that determines whether T is a flat index in the context of child extraction.
Definition childextraction.hh:366
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
Definition accumulate_static.hh:13
Base class for composite nodes based on variadic templates.
Definition compositenode.hh:24
CompositeNode(Args &&... args)
Initialize all children with the passed-in objects.
Definition compositenode.hh:233
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:135
static const bool isLeaf
Mark this class as non leaf in the dune-typetree.
Definition compositenode.hh:38
ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition compositenode.hh:174
Child< k >::Storage childStorage(index_constant< k >={})
Returns the storage of the i-th child.
Definition compositenode.hh:101
static const bool isComposite
Mark this class as a composite in the dune-typetree.
Definition compositenode.hh:44
static const std::size_t CHILDREN
The number of children.
Definition compositenode.hh:47
CompositeNode()
Default constructor.
Definition compositenode.hh:228
CompositeNodeTag NodeTag
The type tag that describes a CompositeNode.
Definition compositenode.hh:29
void setChild(typename Child< k >::Type &child, index_constant< k >={})
Sets the i-th child to the passed-in value.
Definition compositenode.hh:121
void setChild(typename Child< k >::Type &&child, index_constant< k >={})
Store the passed value in k-th child.
Definition compositenode.hh:128
static constexpr std::size_t degree()
Definition compositenode.hh:49
const NodeStorage & nodeStorage() const
Definition compositenode.hh:140
CompositeNode(std::shared_ptr< Children >... children)
Initialize the CompositeNode with copies of the passed in Storage objects.
Definition compositenode.hh:238
Child< k >::ConstStorage childStorage(index_constant< k >={}) const
Returns the storage of the i-th child (const version).
Definition compositenode.hh:114
std::tuple< Children... > ChildTypes
A tuple storing the types of all children.
Definition compositenode.hh:35
const ImplementationDefined & child(Indices... indices)
Returns the child given by the list of indices.
Definition compositenode.hh:197
static const bool isPower
Mark this class as a non power in the dune-typetree.
Definition compositenode.hh:41
Child< k >::Type & child(index_constant< k >={})
Returns the i-th child.
Definition compositenode.hh:81
CompositeNode(const NodeStorage &children)
Initialize the CompositeNode with a copy of the passed-in storage type.
Definition compositenode.hh:243
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition compositenode.hh:32
const Child< k >::Type & child(index_constant< k >={}) const
Returns the i-th child (const version).
Definition compositenode.hh:91
Access to the type and storage type of the i-th child.
Definition compositenode.hh:56
std::tuple_element< k, ChildTypes >::type Type
The type of the child.
Definition compositenode.hh:61
std::tuple_element< k, NodeStorage >::type Storage
The storage type of the child.
Definition compositenode.hh:67
std::tuple_element< k, ChildTypes >::type type
The type of the child.
Definition compositenode.hh:64
std::shared_ptr< const typename std::tuple_element< k, ChildTypes >::type > ConstStorage
The const storage type of the child.
Definition compositenode.hh:70
Tag designating a composite node.
Definition nodetags.hh:22