"Fossies" - the Fresh Open Source Software Archive 
Member "dune-typetree-2.8.0/dune/typetree/compositenode.hh" (31 Aug 2021, 7883 Bytes) of package /linux/misc/dune/dune-typetree-2.8.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "compositenode.hh" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.8.0_vs_2.9.0.
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
15 namespace Dune {
16 namespace TypeTree {
17
18 /** \addtogroup Nodes
19 * \ingroup TypeTree
20 * \{
21 */
22
23 //! Base class for composite nodes based on variadic templates.
24 template<typename... Children>
25 class CompositeNode
26 {
27
28 public:
29
30 //! The type tag that describes a CompositeNode.
31 typedef CompositeNodeTag NodeTag;
32
33 //! The type used for storing the children.
34 typedef std::tuple<std::shared_ptr<Children>... > NodeStorage;
35
36 //! A tuple storing the types of all children.
37 typedef std::tuple<Children...> ChildTypes;
38
39 //! Mark this class as non leaf in the \ref TypeTree.
40 static const bool isLeaf = false;
41
42 //! Mark this class as a non power in the \ref TypeTree.
43 static const bool isPower = false;
44
45 //! Mark this class as a composite in the \ref TypeTree.
46 static const bool isComposite = true;
47
48 //! The number of children.
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
56 //! Access to the type and storage type of the i-th child.
57 template<std::size_t k>
58 struct Child {
59
60 static_assert((k < CHILDREN), "child index out of range");
61
62 //! The type of the child.
63 typedef typename std::tuple_element<k,ChildTypes>::type Type;
64
65 //! The type of the child.
66 typedef typename std::tuple_element<k,ChildTypes>::type type;
67 };
68
69 //! @name Child Access
70 //! @{
71
72 //! Returns the k-th child.
73 /**
74 * \returns a reference to the k-th child.
75 */
76 template<std::size_t k>
77 typename Child<k>::Type& child (index_constant<k> = {})
78 {
79 return *std::get<k>(_children);
80 }
81
82 //! Returns the k-th child (const version).
83 /**
84 * \returns a const reference to the k-th child.
85 */
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
92 //! Returns the storage of the k-th child.
93 /**
94 * \returns a copy of the object storing the k-th child.
95 */
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
102 //! Returns the storage of the k-th child (const version).
103 /**
104 * \returns a copy of the object storing the k-th child.
105 */
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
112 //! Sets the k-th child to the passed-in value.
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
119 //! Store the passed value in k-th child.
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
126 //! Sets the storage of the k-th child to the passed-in value.
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
138 //! @}
139
140 //! @name Nested Child Access
141 //! @{
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
160 //! Returns the child given by the list of indices.
161 /**
162 * This method simply forwards to the freestanding function child(). See that
163 * function for further information.
164 */
165 #ifdef DOXYGEN
166 template<typename... Indices>
167 ImplementationDefined& child (Indices... 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
180 //! Returns the child given by the list of indices.
181 /**
182 * This method simply forwards to the freestanding function child(). See that
183 * function for further information.
184 */
185 #ifdef DOXYGEN
186 template<typename... Indices>
187 const ImplementationDefined& child (Indices... 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
200 //! @}
201
202 protected:
203
204 //! @name Constructors
205 //! @{
206
207 //! Default constructor.
208 /**
209 * This constructor requires the storage type to be default
210 * constructible.
211 * \warning If the storage type is a pointer, the resulting object
212 * will not be usable before its children are set using any of the
213 * setChild(...) methods!
214 */
215 CompositeNode ()
216 {}
217
218 //! Initialize all children with the passed-in objects.
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
224 //! Initialize the CompositeNode with copies of the passed in Storage objects.
225 CompositeNode (std::shared_ptr<Children>... children)
226 : _children(std::move(children)...)
227 {}
228
229 //! Initialize the CompositeNode with a copy of the passed-in storage type.
230 CompositeNode (const NodeStorage& children)
231 : _children(children)
232 {}
233
234 //! @}
235
236 private:
237 NodeStorage _children;
238 };
239
240 //! \} group Nodes
241
242 } // namespace TypeTree
243 } //namespace Dune
244
245 #endif // DUNE_TYPETREE_COMPOSITENODE_HH