4#ifndef DUNE_TYPETREE_TRANSFORMATION_HH
5#define DUNE_TYPETREE_TRANSFORMATION_HH
12#include <dune/common/hybridutilities.hh>
13#include <dune/common/exceptions.hh>
14#include <dune/common/typetraits.hh>
51 template<
typename SourceNode,
typename Transformation,
typename Tag>
66 template<
typename S,
typename T,
typename Tag>
67 struct LookupNodeTransformation
76 static_assert((!std::is_same<type,void>::value),
"Unable to find valid transformation descriptor");
92 template<
typename SourceTree,
typename Transformation,
typename Tag = StartTag,
bool recursive = true>
98 typedef typename LookupNodeTransformation<SourceTree,Transformation,typename SourceTree::ImplementationTag>::type NodeTransformation;
114 static transformed_type
transform(
const SourceTree& s,
const Transformation& t = Transformation())
120 static transformed_type
transform(
const SourceTree& s, Transformation& t)
126 static transformed_type
transform(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
132 static transformed_type
transform(std::shared_ptr<const SourceTree> sp, Transformation& t)
139 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
146 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp, Transformation& t)
157 template<
typename S,
typename T,
bool recursive>
158 struct TransformTree<S,T,LeafNodeTag,recursive>
161 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>
::type NodeTransformation;
163 typedef typename NodeTransformation::transformed_type transformed_type;
164 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
167 static transformed_type
transform(
const S& s, T& t)
169 return NodeTransformation::transform(s,t);
173 static transformed_type
transform(
const S& s,
const T& t)
175 return NodeTransformation::transform(s,t);
179 static transformed_type
transform(std::shared_ptr<const S> sp, T& t)
181 return NodeTransformation::transform(sp,t);
185 static transformed_type
transform(std::shared_ptr<const S> sp,
const T& t)
187 return NodeTransformation::transform(sp,t);
190 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp, T& t)
192 return NodeTransformation::transform_storage(sp,t);
195 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp,
const T& t)
197 return NodeTransformation::transform_storage(sp,t);
204 template<
typename S,
typename T>
205 struct TransformTreeNonRecursive
208 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>::type NodeTransformation;
210 typedef typename NodeTransformation::transformed_type transformed_type;
211 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
214 static transformed_type transform(
const S& s, T& t)
216 return NodeTransformation::transform(s,t);
220 static transformed_type transform(
const S& s,
const T& t)
222 return NodeTransformation::transform(s,t);
226 static transformed_type transform(std::shared_ptr<const S> sp, T& t)
228 return NodeTransformation::transform(sp,t);
232 static transformed_type transform(std::shared_ptr<const S> sp,
const T& t)
234 return NodeTransformation::transform(sp,t);
237 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
239 return NodeTransformation::transform_storage(sp,t);
242 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
244 return NodeTransformation::transform_storage(sp,t);
253 template<
class Source,
class Transformation,
class Tag>
254 class RecursivePowerTransformTree
257 static_assert(std::is_same_v<Tag,PowerNodeTag> or std::is_same_v<Tag,DynamicPowerNodeTag>);
259 using ChildType =
typename Source::ChildType;
262 template<
class NodeStorage>
263 static auto node_storage_provider(
const std::size_t&
degree)
265 return std::vector<NodeStorage>(
degree);
269 template<
class NodeStorage,
class StaticIndex>
270 static auto node_storage_provider(StaticIndex)
272 return std::array<NodeStorage,std::size_t(StaticIndex{})>();
283 using NodeTransformation =
typename LookupNodeTransformation<Source,Transformation,ImplementationTag<Source>>::type;
284 using ChildNodeTransformation =
typename LookupNodeTransformation<ChildType,Transformation,ImplementationTag<ChildType>>::type;
288 using ChildTreeTransformation = TransformTree<ChildType,
291 ChildNodeTransformation::recursive>;
294 using transformed_child_type =
typename ChildTreeTransformation::transformed_type;
295 using transformed_child_storage_type =
typename ChildTreeTransformation::transformed_storage_type;
298 using transformed_type =
typename NodeTransformation::template result<transformed_child_type>::type;
299 using transformed_storage_type =
typename NodeTransformation::template result<transformed_child_type>::storage_type;
302 static transformed_type transform(
const Source& source, Transformation& transformation)
304 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source.degree());
305 for (std::size_t k = 0; k < source.degree(); ++k) {
306 children_storage[k] = ChildTreeTransformation::transform_storage(source.childStorage(k),transformation);
308 return NodeTransformation::transform(source,transformation,children_storage);
312 static transformed_type transform(
const Source& source,
const Transformation& transformation)
314 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source.degree());
315 for (std::size_t k = 0; k < source.degree(); ++k) {
316 children_storage[k] = ChildTreeTransformation::transform_storage(source.childStorage(k),transformation);
318 return NodeTransformation::transform(source,transformation,children_storage);
322 static transformed_type transform(std::shared_ptr<const Source> source_ptr, Transformation& transformation)
324 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source_ptr->degree());
325 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
326 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
328 return NodeTransformation::transform(source_ptr,transformation,children_storage);
332 static transformed_type transform(std::shared_ptr<const Source> source_ptr,
const Transformation& transformation)
334 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source_ptr->degree());
335 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
336 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
338 return NodeTransformation::transform(source_ptr,transformation,children_storage);
342 static transformed_storage_type transform_storage(std::shared_ptr<const Source> source_ptr, Transformation& transformation)
344 auto children_storage = node_storage_provider<transformed_child_storage_type>(source_ptr->degree());
345 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
346 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
348 return NodeTransformation::transform_storage(source_ptr,transformation,children_storage);
352 static transformed_storage_type transform_storage(std::shared_ptr<const Source> source_ptr,
const Transformation& transformation)
354 auto children_storage = node_storage_provider<transformed_child_storage_type>(source_ptr->degree());
355 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
356 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
358 return NodeTransformation::transform_storage(source_ptr,transformation,children_storage);
365 template<
typename Source,
typename Transformation>
366 struct TransformTree<Source,Transformation,PowerNodeTag,true>
367 :
public Impl::RecursivePowerTransformTree<Source,Transformation,PowerNodeTag>
371 template<
typename Source,
typename Transformation>
372 struct TransformTree<Source,Transformation,DynamicPowerNodeTag,true>
373 :
public Impl::RecursivePowerTransformTree<Source,Transformation,DynamicPowerNodeTag>
377 template<
typename S,
typename T>
378 struct TransformTree<S,T,PowerNodeTag,false>
379 :
public TransformTreeNonRecursive<S,T>
383 template<
typename S,
typename T>
384 struct TransformTree<S,T,DynamicPowerNodeTag,false>
385 :
public TransformTreeNonRecursive<S,T>
393 template<
typename S,
typename Children,
typename T>
394 struct transform_composite_node;
399 template<
typename S,
typename T,
typename... C>
400 struct transform_composite_node<S,std::tuple<C...>,T>
404 typedef ImplementationTag<S> Tag;
405 typedef typename LookupNodeTransformation<S,T,Tag>::type NodeTransformation;
406 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
409 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
410 >::transformed_type...
411 >::type transformed_type;
413 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
416 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
417 >::transformed_type...
418 >::storage_type transformed_storage_type;
423 template<std::
size_t i>
424 struct ChildTransformation
425 :
public TransformTree<typename S::template Child<i>::Type,
427 NodeTag<typename S::template Child<i>::Type>,
428 LookupNodeTransformation<
429 typename S::template Child<i>::Type,
431 ImplementationTag<typename S::template Child<i>::Type>
436 template<std::
size_t i,
typename Tuple,
typename Value>
437 static void setElement(Tuple& tuple, Value&& value)
439 std::get<i>(tuple) = std::forward<Value>(value);
442 template<
typename Trafo, std::size_t... i>
443 static transformed_type transform(
const S& s, Trafo&& t, std::index_sequence<i...> indices)
445 std::tuple<typename ChildTransformation<i>::transformed_storage_type...> storage;
446 Dune::Hybrid::Impl::evaluateFoldExpression<int>({(setElement<i>(storage, ChildTransformation<i>::transform_storage(s.template childStorage<i>(), std::forward<Trafo>(t))),0)...});
447 return NodeTransformation::transform(s, std::forward<Trafo>(t), std::get<i>(storage)...);
450 template<
typename Trafo, std::size_t... i>
451 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, Trafo&& t, std::index_sequence<i...> indices)
453 std::tuple<typename ChildTransformation<i>::transformed_storage_type...> storage;
454 Dune::Hybrid::Impl::evaluateFoldExpression<int>({(setElement<i>(storage, ChildTransformation<i>::transform_storage(sp->template childStorage<i>(), std::forward<Trafo>(t))),0)...});
455 return NodeTransformation::transform_storage(sp, std::forward<Trafo>(t), std::get<i>(storage)...);
462 template<
typename S,
typename T>
463 struct TransformTree<S,T,CompositeNodeTag,true>
468 typedef typename S::ChildTypes ChildTypes;
470 static auto child_indices()
472 return std::make_index_sequence<S::CHILDREN>();
477 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_type transformed_type;
478 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_storage_type transformed_storage_type;
480 static transformed_type
transform(
const S& s, T& t)
482 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
485 static transformed_type
transform(
const S& s,
const T& t)
487 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
490 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp, T& t)
492 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
495 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp,
const T& t)
497 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
503 template<
typename S,
typename T>
504 struct TransformTree<S,T,CompositeNodeTag,false>
505 :
public TransformTreeNonRecursive<S,T>
static const result_type result
Definition: accumulate_static.hh:110
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:76
void registerNodeTransformation(SourceNode *, Transformation *, Tag *)
Register transformation descriptor to transform SourceNode with Transformation.
Definition: accumulate_static.hh:13
Transform a TypeTree.
Definition: transformation.hh:94
type Type
Definition: transformation.hh:111
static transformed_type transform(std::shared_ptr< const SourceTree > sp, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:132
static transformed_type transform(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:126
static transformed_type transform(const SourceTree &s, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:120
transformed_type type
The type of the transformed tree.
Definition: transformation.hh:109
static transformed_type transform(const SourceTree &s, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:114
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Definition: transformation.hh:139
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, Transformation &t)
Definition: transformation.hh:146
Meta function that evaluates its argument iff it inherits from meta_function.
Definition: typetraits.hh:148