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
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;
112 static transformed_type
transform(
const SourceTree& s,
const Transformation& t = Transformation())
118 static transformed_type
transform(
const SourceTree& s, Transformation& t)
124 static transformed_type
transform(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
130 static transformed_type
transform(std::shared_ptr<const SourceTree> sp, Transformation& t)
137 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
144 static transformed_storage_type
transform_storage(std::shared_ptr<const SourceTree> sp, Transformation& t)
155 template<
typename S,
typename T,
bool recursive>
156 struct TransformTree<S,T,LeafNodeTag,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>
250 struct TransformTree<S,T,PowerNodeTag,true>
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,
264 NodeTag<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)
278 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
279 typedef typename ChildTreeTransformation::transformed_type transformed_child;
280 const std::size_t child_count = StaticDegree<S>::value;
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)
292 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
293 typedef typename ChildTreeTransformation::transformed_type transformed_child;
294 const std::size_t child_count = StaticDegree<S>::value;
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)
307 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
308 typedef typename ChildTreeTransformation::transformed_type transformed_child;
309 const std::size_t child_count = StaticDegree<S>::value;
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)
321 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
322 typedef typename ChildTreeTransformation::transformed_type transformed_child;
323 const std::size_t child_count = StaticDegree<S>::value;
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)
335 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
336 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
337 const std::size_t child_count = StaticDegree<S>::value;
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)
348 typedef TransformTree<typename S::ChildType,T,NodeTag<typename S::ChildType>,ChildNodeTransformation::recursive> ChildTreeTransformation;
349 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
350 const std::size_t child_count = StaticDegree<S>::value;
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>
362 struct TransformTree<S,T,PowerNodeTag,false>
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>
382 typedef ImplementationTag<S> Tag;
383 typedef typename LookupNodeTransformation<S,T,Tag>::type NodeTransformation;
384 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
387 LookupNodeTransformation<C,T,ImplementationTag<C>>::type::recursive
388 >::transformed_type...
389 >::type transformed_type;
391 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
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
403 :
public TransformTree<typename S::template Child<i>::Type,
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>
445 struct TransformTree<S,T,CompositeNodeTag,true>
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>
486 struct TransformTree<S,T,CompositeNodeTag,false>
487 :
public TransformTreeNonRecursive<S,T>
static const result_type result
Definition accumulate_static.hh:110
void registerNodeTransformation(SourceNode *, Transformation *, Tag *)
Register transformation descriptor to transform SourceNode with Transformation.
Definition accumulate_static.hh:13
Transform a TypeTree.
Definition transformation.hh:92
type Type
Definition transformation.hh:109
static transformed_type transform(std::shared_ptr< const SourceTree > sp, Transformation &t)
Apply transformation to an existing tree s.
Definition transformation.hh:130
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
static transformed_type transform(const SourceTree &s, Transformation &t)
Apply transformation to an existing tree s.
Definition transformation.hh:118
transformed_type type
The type of the transformed tree.
Definition transformation.hh:107
static transformed_type transform(const SourceTree &s, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition transformation.hh:112
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Definition transformation.hh:137
static transformed_storage_type transform_storage(std::shared_ptr< const SourceTree > sp, Transformation &t)
Definition transformation.hh:144
Meta function that evaluates its argument iff it inherits from meta_function.
Definition typetraits.hh:148
index_pack< 0, 1,..., n-1 > type
Result.
Definition utility.hh:217