4 #ifndef DUNE_TYPETREE_TRANSFORMATION_HH 5 #define DUNE_TYPETREE_TRANSFORMATION_HH 11 #include <dune/common/exceptions.hh> 12 #include <dune/common/typetraits.hh> 49 template<
typename SourceNode,
typename Transformation,
typename Tag>
64 template<
typename S,
typename T,
typename Tag>
65 struct LookupNodeTransformation
70 typedef typename evaluate_if_meta_function<
74 static_assert((!
std::is_same<type,
void>::value), "Unable to find valid transformation descriptor");
90 template<
typename SourceTree,
typename Transformation,
typename Tag = StartTag,
bool recursive = true>
96 typedef typename LookupNodeTransformation<SourceTree,Transformation,typename SourceTree::ImplementationTag>::type NodeTransformation;
102 typedef typename TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transformed_storage_type transformed_storage_type;
112 static transformed_type
transform(
const SourceTree& s,
const Transformation& t = Transformation())
114 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform(s,t);
118 static transformed_type
transform(
const SourceTree& s, Transformation& t)
120 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform(s,t);
124 static transformed_type
transform(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
126 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform(sp,t);
130 static transformed_type
transform(std::shared_ptr<const SourceTree> sp, Transformation& t)
132 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform(sp,t);
137 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
139 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform_storage(sp,t);
144 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp, Transformation& t)
146 return TransformTree<SourceTree,Transformation,NodeTag<SourceTree>,NodeTransformation::recursive>::transform_storage(sp,t);
152 #ifndef DOXYGEN // internal per-node implementations of the transformation algorithm 155 template<
typename S,
typename T,
bool recursive>
159 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>
::type NodeTransformation;
161 typedef typename NodeTransformation::transformed_type transformed_type;
162 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
165 static transformed_type transform(
const S& s, T& t)
167 return NodeTransformation::transform(s,t);
171 static transformed_type transform(
const S& s,
const T& t)
173 return NodeTransformation::transform(s,t);
177 static transformed_type transform(std::shared_ptr<const S> sp, T& t)
179 return NodeTransformation::transform(sp,t);
183 static transformed_type transform(std::shared_ptr<const S> sp,
const T& t)
185 return NodeTransformation::transform(sp,t);
188 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
190 return NodeTransformation::transform_storage(sp,t);
193 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
195 return NodeTransformation::transform_storage(sp,t);
202 template<
typename S,
typename T>
203 struct TransformTreeNonRecursive
206 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>
::type NodeTransformation;
208 typedef typename NodeTransformation::transformed_type transformed_type;
209 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
212 static transformed_type transform(
const S& s, T& t)
214 return NodeTransformation::transform(s,t);
218 static transformed_type transform(
const S& s,
const T& t)
220 return NodeTransformation::transform(s,t);
224 static transformed_type transform(std::shared_ptr<const S> sp, T& t)
226 return NodeTransformation::transform(sp,t);
230 static transformed_type transform(std::shared_ptr<const S> sp,
const T& t)
232 return NodeTransformation::transform(sp,t);
235 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
237 return NodeTransformation::transform_storage(sp,t);
240 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
242 return NodeTransformation::transform_storage(sp,t);
249 template<
typename S,
typename T>
259 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>
::type NodeTransformation;
260 typedef typename LookupNodeTransformation<typename S::ChildType,T,ImplementationTag<typename S::ChildType>>
::type ChildNodeTransformation;
262 typedef typename NodeTransformation::template
result<
typename TransformTree<
typename S::ChildType,
265 ChildNodeTransformation::recursive>::transformed_type
268 typedef typename NodeTransformation::template
result<
typename TransformTree<
typename S::ChildType,
270 NodeTag<typename S::ChildType>,
271 ChildNodeTransformation::recursive>::transformed_type
272 >::storage_type transformed_storage_type;
275 static transformed_type transform(
const S& s, T& t)
279 typedef typename ChildTreeTransformation::transformed_type transformed_child;
281 std::array<std::shared_ptr<transformed_child>,child_count> children;
282 for (std::size_t k = 0; k < child_count; ++k) {
283 children[k] = ChildTreeTransformation::transform_storage(s.childStorage(k),t);
286 return NodeTransformation::transform(s,t,children);
289 static transformed_type transform(
const S& s,
const T& t)
293 typedef typename ChildTreeTransformation::transformed_type transformed_child;
295 std::array<std::shared_ptr<transformed_child>,child_count> children;
296 for (std::size_t k = 0; k < child_count; ++k) {
297 children[k] = ChildTreeTransformation::transform_storage(s.childStorage(k),t);
300 return NodeTransformation::transform(s,t,children);
304 static transformed_type transform(std::shared_ptr<const S> sp, T& t)
308 typedef typename ChildTreeTransformation::transformed_type transformed_child;
310 std::array<std::shared_ptr<transformed_child>,child_count> children;
311 for (std::size_t k = 0; k < child_count; ++k) {
312 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
315 return NodeTransformation::transform(sp,t,children);
318 static transformed_type transform(std::shared_ptr<const S> sp,
const T& t)
322 typedef typename ChildTreeTransformation::transformed_type transformed_child;
324 std::array<std::shared_ptr<transformed_child>,child_count> children;
325 for (std::size_t k = 0; k < child_count; ++k) {
326 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
329 return NodeTransformation::transform(sp,t,children);
332 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
336 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
338 std::array<transformed_child_storage,child_count> children;
339 for (std::size_t k = 0; k < child_count; ++k) {
340 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
342 return NodeTransformation::transform_storage(sp,t,children);
345 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
349 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
351 std::array<transformed_child_storage,child_count> children;
352 for (std::size_t k = 0; k < child_count; ++k) {
353 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
355 return NodeTransformation::transform_storage(sp,t,children);
361 template<
typename S,
typename T>
363 :
public TransformTreeNonRecursive<S,T>
371 template<
typename S,
typename Children,
typename T>
372 struct transform_composite_node;
377 template<
typename S,
typename T,
typename... C>
378 struct transform_composite_node<S,std::tuple<C...>,T>
383 typedef typename LookupNodeTransformation<S,T,Tag>::type NodeTransformation;
387 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
388 >::transformed_type...
394 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
395 >::transformed_type...
396 >::storage_type transformed_storage_type;
401 template<std::
size_t i>
402 struct ChildTransformation
405 NodeTag<typename S::template Child<i>::Type>,
406 LookupNodeTransformation<
407 typename S::template Child<i>::Type,
409 ImplementationTag<typename S::template Child<i>::Type>
415 template<std::size_t... i>
416 static transformed_type transform(
const S& s, T& t,
index_pack<i...> indices)
418 return NodeTransformation::transform(s,t,ChildTransformation<i>::transform_storage(s.template childStorage<i>(),t)...);
421 template<std::size_t... i>
422 static transformed_type transform(
const S& s,
const T& t,
index_pack<i...> indices)
424 return NodeTransformation::transform(s,t,ChildTransformation<i>::transform_storage(s.template childStorage<i>(),t)...);
427 template<std::size_t... i>
428 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t,
index_pack<i...> indices)
430 return NodeTransformation::transform_storage(sp,t,ChildTransformation<i>::transform_storage(sp->template childStorage<i>(),t)...);
433 template<std::size_t... i>
434 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t,
index_pack<i...> indices)
436 return NodeTransformation::transform_storage(sp,t,ChildTransformation<i>::transform_storage(sp->template childStorage<i>(),t)...);
444 template<
typename S,
typename T>
450 typedef typename S::ChildTypes ChildTypes;
459 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_type transformed_type;
460 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_storage_type transformed_storage_type;
462 static transformed_type transform(
const S& s, T& t)
464 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
467 static transformed_type transform(
const S& s,
const T& t)
469 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
472 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
474 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
477 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
479 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
485 template<
typename S,
typename T>
487 :
public TransformTreeNonRecursive<S,T>
497 #endif // DUNE_TYPETREE_TRANSFORMATION_HH static transformed_type transform(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:124
Simple holder class for a template argument pack of indices.
Definition: utility.hh:207
static transformed_type transform(const SourceTree &s, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:112
typename std::decay_t< T >::ImplementationTag ImplementationTag
Returns the implementation tag of the given Node.
Definition: nodeinterface.hh:66
static transformed_type transform(const SourceTree &s, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:118
index_pack< 0, 1,..., n-1 > type
Result.
Definition: utility.hh:217
Definition: accumulate_static.hh:13
transformed_type type
The type of the transformed tree.
Definition: transformation.hh:107
type Type
Definition: transformation.hh:109
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, Transformation &t)
Definition: transformation.hh:144
static const result_type result
Definition: accumulate_static.hh:110
std::integral_constant< std::size_t, degree(static_cast< std::decay_t< Node > * >(nullptr), NodeTag< std::decay_t< Node >>()) > StaticDegree
Returns the statically known degree of the given Node type as a std::integral_constant.
Definition: nodeinterface.hh:105
Transform a TypeTree.
Definition: transformation.hh:91
static transformed_type transform(std::shared_ptr< const SourceTree > sp, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:130
typename std::decay_t< Node >::NodeTag NodeTag
Returns the node tag of the given Node.
Definition: nodeinterface.hh:62
void registerNodeTransformation(SourceNode *, Transformation *, Tag *)
Register transformation descriptor to transform SourceNode with Transformation.
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Definition: transformation.hh:137