6#ifndef DUNE_TYPETREE_TRANSFORMATION_HH
7#define DUNE_TYPETREE_TRANSFORMATION_HH
14#include <dune/common/hybridutilities.hh>
15#include <dune/common/exceptions.hh>
16#include <dune/common/typetraits.hh>
53 template<
typename SourceNode,
typename Transformation,
typename Tag>
68 template<
typename S,
typename T,
typename Tag>
69 struct LookupNodeTransformation
78 static_assert((!std::is_same<type,void>::value),
"Unable to find valid transformation descriptor");
94 template<
typename SourceTree,
typename Transformation,
typename Tag = StartTag,
bool recursive = true>
100 typedef typename LookupNodeTransformation<SourceTree,Transformation,typename SourceTree::ImplementationTag>::type NodeTransformation;
116 static transformed_type
transform(
const SourceTree& s,
const Transformation& t = Transformation())
122 static transformed_type
transform(
const SourceTree& s, Transformation& t)
128 static transformed_type
transform(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
134 static transformed_type
transform(std::shared_ptr<const SourceTree> sp, Transformation& t)
141 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
148 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp, Transformation& t)
159 template<
typename S,
typename T,
bool recursive>
160 struct TransformTree<S,T,LeafNodeTag,recursive>
163 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>
::type NodeTransformation;
165 typedef typename NodeTransformation::transformed_type transformed_type;
166 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
169 static transformed_type
transform(
const S& s, T& t)
171 return NodeTransformation::transform(s,t);
175 static transformed_type
transform(
const S& s,
const T& t)
177 return NodeTransformation::transform(s,t);
181 static transformed_type
transform(std::shared_ptr<const S> sp, T& t)
183 return NodeTransformation::transform(sp,t);
187 static transformed_type
transform(std::shared_ptr<const S> sp,
const T& t)
189 return NodeTransformation::transform(sp,t);
192 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp, T& t)
194 return NodeTransformation::transform_storage(sp,t);
197 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp,
const T& t)
199 return NodeTransformation::transform_storage(sp,t);
206 template<
typename S,
typename T>
207 struct TransformTreeNonRecursive
210 typedef typename LookupNodeTransformation<S,T,ImplementationTag<S>>::type NodeTransformation;
212 typedef typename NodeTransformation::transformed_type transformed_type;
213 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
216 static transformed_type transform(
const S& s, T& t)
218 return NodeTransformation::transform(s,t);
222 static transformed_type transform(
const S& s,
const T& t)
224 return NodeTransformation::transform(s,t);
228 static transformed_type transform(std::shared_ptr<const S> sp, T& t)
230 return NodeTransformation::transform(sp,t);
234 static transformed_type transform(std::shared_ptr<const S> sp,
const T& t)
236 return NodeTransformation::transform(sp,t);
239 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, T& t)
241 return NodeTransformation::transform_storage(sp,t);
244 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp,
const T& t)
246 return NodeTransformation::transform_storage(sp,t);
255 template<
class Source,
class Transformation,
class Tag>
256 class RecursivePowerTransformTree
259 static_assert(std::is_same_v<Tag,PowerNodeTag> or std::is_same_v<Tag,DynamicPowerNodeTag>);
261 using ChildType =
typename Source::ChildType;
264 template<
class NodeStorage>
265 static auto node_storage_provider(
const std::size_t& degree)
267 return std::vector<NodeStorage>(degree);
271 template<
class NodeStorage,
class StaticIndex>
272 static auto node_storage_provider(StaticIndex)
274 return std::array<NodeStorage,std::size_t(StaticIndex{})>();
285 using NodeTransformation =
typename LookupNodeTransformation<Source,Transformation,ImplementationTag<Source>>::type;
286 using ChildNodeTransformation =
typename LookupNodeTransformation<ChildType,Transformation,ImplementationTag<ChildType>>::type;
290 using ChildTreeTransformation = TransformTree<ChildType,
293 ChildNodeTransformation::recursive>;
296 using transformed_child_type =
typename ChildTreeTransformation::transformed_type;
297 using transformed_child_storage_type =
typename ChildTreeTransformation::transformed_storage_type;
300 using transformed_type =
typename NodeTransformation::template result<transformed_child_type>::type;
301 using transformed_storage_type =
typename NodeTransformation::template result<transformed_child_type>::storage_type;
304 static transformed_type transform(
const Source& source, Transformation& transformation)
306 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source.degree());
307 for (std::size_t k = 0; k < source.degree(); ++k) {
308 children_storage[k] = ChildTreeTransformation::transform_storage(source.childStorage(k),transformation);
310 return NodeTransformation::transform(source,transformation,children_storage);
314 static transformed_type transform(
const Source& source,
const Transformation& transformation)
316 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source.degree());
317 for (std::size_t k = 0; k < source.degree(); ++k) {
318 children_storage[k] = ChildTreeTransformation::transform_storage(source.childStorage(k),transformation);
320 return NodeTransformation::transform(source,transformation,children_storage);
324 static transformed_type transform(std::shared_ptr<const Source> source_ptr, Transformation& transformation)
326 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source_ptr->degree());
327 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
328 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
330 return NodeTransformation::transform(source_ptr,transformation,children_storage);
334 static transformed_type transform(std::shared_ptr<const Source> source_ptr,
const Transformation& transformation)
336 auto children_storage = node_storage_provider<std::shared_ptr<transformed_child_type>>(source_ptr->degree());
337 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
338 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
340 return NodeTransformation::transform(source_ptr,transformation,children_storage);
344 static transformed_storage_type transform_storage(std::shared_ptr<const Source> source_ptr, Transformation& transformation)
346 auto children_storage = node_storage_provider<transformed_child_storage_type>(source_ptr->degree());
347 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
348 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
350 return NodeTransformation::transform_storage(source_ptr,transformation,children_storage);
354 static transformed_storage_type transform_storage(std::shared_ptr<const Source> source_ptr,
const Transformation& transformation)
356 auto children_storage = node_storage_provider<transformed_child_storage_type>(source_ptr->degree());
357 for (std::size_t k = 0; k < source_ptr->degree(); ++k) {
358 children_storage[k] = ChildTreeTransformation::transform_storage(source_ptr->childStorage(k),transformation);
360 return NodeTransformation::transform_storage(source_ptr,transformation,children_storage);
367 template<
typename Source,
typename Transformation>
368 struct TransformTree<Source,Transformation,PowerNodeTag,true>
369 :
public Impl::RecursivePowerTransformTree<Source,Transformation,PowerNodeTag>
373 template<
typename Source,
typename Transformation>
374 struct TransformTree<Source,Transformation,DynamicPowerNodeTag,true>
375 :
public Impl::RecursivePowerTransformTree<Source,Transformation,DynamicPowerNodeTag>
379 template<
typename S,
typename T>
380 struct TransformTree<S,T,PowerNodeTag,false>
381 :
public TransformTreeNonRecursive<S,T>
385 template<
typename S,
typename T>
386 struct TransformTree<S,T,DynamicPowerNodeTag,false>
387 :
public TransformTreeNonRecursive<S,T>
395 template<
typename S,
typename Children,
typename T>
396 struct transform_composite_node;
401 template<
typename S,
typename T,
typename... C>
402 struct transform_composite_node<S,std::tuple<C...>,T>
406 typedef ImplementationTag<S> Tag;
407 typedef typename LookupNodeTransformation<S,T,Tag>::type NodeTransformation;
408 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
411 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
412 >::transformed_type...
413 >::type transformed_type;
415 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
418 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
419 >::transformed_type...
420 >::storage_type transformed_storage_type;
425 template<std::
size_t i>
426 struct ChildTransformation
427 :
public TransformTree<typename S::template Child<i>::Type,
429 NodeTag<typename S::template Child<i>::Type>,
430 LookupNodeTransformation<
431 typename S::template Child<i>::Type,
433 ImplementationTag<typename S::template Child<i>::Type>
438 template<std::
size_t i,
typename Tuple,
typename Value>
439 static void setElement(Tuple& tuple, Value&& value)
441 std::get<i>(tuple) = std::forward<Value>(value);
444 template<
typename Trafo, std::size_t... i>
445 static transformed_type transform(
const S& s, Trafo&& t, std::index_sequence<i...> indices)
447 std::tuple<typename ChildTransformation<i>::transformed_storage_type...> storage;
448 Dune::Hybrid::Impl::evaluateFoldExpression<int>({(setElement<i>(storage, ChildTransformation<i>::transform_storage(s.template childStorage<i>(), std::forward<Trafo>(t))),0)...});
449 return NodeTransformation::transform(s, std::forward<Trafo>(t), std::get<i>(storage)...);
452 template<
typename Trafo, std::size_t... i>
453 static transformed_storage_type transform_storage(std::shared_ptr<const S> sp, Trafo&& t, std::index_sequence<i...> indices)
455 std::tuple<typename ChildTransformation<i>::transformed_storage_type...> storage;
456 Dune::Hybrid::Impl::evaluateFoldExpression<int>({(setElement<i>(storage, ChildTransformation<i>::transform_storage(sp->template childStorage<i>(), std::forward<Trafo>(t))),0)...});
457 return NodeTransformation::transform_storage(sp, std::forward<Trafo>(t), std::get<i>(storage)...);
464 template<
typename S,
typename T>
465 struct TransformTree<S,T,CompositeNodeTag,true>
470 typedef typename S::ChildTypes ChildTypes;
472 static auto child_indices()
474 return std::make_index_sequence<S::degree()>();
479 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_type transformed_type;
480 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_storage_type transformed_storage_type;
482 static transformed_type
transform(
const S& s, T& t)
484 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
487 static transformed_type
transform(
const S& s,
const T& t)
489 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
492 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp, T& t)
494 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
497 static transformed_storage_type
transform_storage(std::shared_ptr<const S> sp,
const T& t)
499 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
505 template<
typename S,
typename T>
506 struct TransformTree<S,T,CompositeNodeTag,false>
507 :
public TransformTreeNonRecursive<S,T>
static const result_type result
Definition accumulate_static.hh:113
void registerNodeTransformation(SourceNode *, Transformation *, Tag *)
Register transformation descriptor to transform SourceNode with Transformation.
Definition accumulate_static.hh:16
Transform a TypeTree.
Definition transformation.hh:96
type Type
Definition transformation.hh:113
static transformed_type transform(std::shared_ptr< const SourceTree > sp, Transformation &t)
Apply transformation to an existing tree s.
Definition transformation.hh:134
static transformed_type transform(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition transformation.hh:128
static transformed_type transform(const SourceTree &s, Transformation &t)
Apply transformation to an existing tree s.
Definition transformation.hh:122
transformed_type type
The type of the transformed tree.
Definition transformation.hh:111
static transformed_type transform(const SourceTree &s, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition transformation.hh:116
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Definition transformation.hh:141
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, Transformation &t)
Definition transformation.hh:148
Meta function that evaluates its argument iff it inherits from meta_function.
Definition typetraits.hh:142