4 #ifndef DUNE_TYPETREE_TRANSFORMATION_HH
5 #define DUNE_TYPETREE_TRANSFORMATION_HH
9 #include <dune/common/exceptions.hh>
10 #include <dune/common/typetraits.hh>
11 #include <dune/common/shared_ptr.hh>
12 #include <dune/common/tuples.hh>
48 template<
typename SourceNode,
typename Transformation,
typename Tag>
63 template<
typename S,
typename T,
typename Tag>
64 struct LookupNodeTransformation
69 typedef typename evaluate_if_meta_function<
73 static_assert((!is_same<type,
void>::value), "Unable to find valid transformation descriptor");
89 template<
typename SourceTree,
typename Transformation,
typename Tag = StartTag,
bool recursive = true>
95 typedef typename LookupNodeTransformation<SourceTree,Transformation,typename SourceTree::ImplementationTag>::type NodeTransformation;
111 static transformed_type
transform(
const SourceTree& s,
const Transformation& t = Transformation())
117 static transformed_type
transform(
const SourceTree& s, Transformation& t)
123 static transformed_type
transform(shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
129 static transformed_type
transform(shared_ptr<const SourceTree> sp, Transformation& t)
136 static transformed_storage_type
transform_storage(shared_ptr<const SourceTree> sp,
const Transformation& t = Transformation())
143 static transformed_storage_type
transform_storage(shared_ptr<const SourceTree> sp, Transformation& t)
151 #ifndef DOXYGEN // internal per-node implementations of the transformation algorithm
154 template<
typename S,
typename T,
bool recursive>
155 struct TransformTree<S,T,LeafNodeTag,recursive>
158 typedef typename LookupNodeTransformation<S,T,typename S::ImplementationTag>::type NodeTransformation;
160 typedef typename NodeTransformation::transformed_type transformed_type;
161 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
164 static transformed_type transform(
const S& s, T& t)
166 return NodeTransformation::transform(s,t);
170 static transformed_type transform(
const S& s,
const T& t)
172 return NodeTransformation::transform(s,t);
176 static transformed_type transform(shared_ptr<const S> sp, T& t)
178 return NodeTransformation::transform(sp,t);
182 static transformed_type transform(shared_ptr<const S> sp,
const T& t)
184 return NodeTransformation::transform(sp,t);
187 static transformed_storage_type transform_storage(shared_ptr<const S> sp, T& t)
189 return NodeTransformation::transform_storage(sp,t);
192 static transformed_storage_type transform_storage(shared_ptr<const S> sp,
const T& t)
194 return NodeTransformation::transform_storage(sp,t);
201 template<
typename S,
typename T>
202 struct TransformTreeNonRecursive
205 typedef typename LookupNodeTransformation<S,T,typename S::ImplementationTag>::type NodeTransformation;
207 typedef typename NodeTransformation::transformed_type transformed_type;
208 typedef typename NodeTransformation::transformed_storage_type transformed_storage_type;
211 static transformed_type transform(
const S& s, T& t)
213 return NodeTransformation::transform(s,t);
217 static transformed_type transform(
const S& s,
const T& t)
219 return NodeTransformation::transform(s,t);
223 static transformed_type transform(shared_ptr<const S> sp, T& t)
225 return NodeTransformation::transform(sp,t);
229 static transformed_type transform(shared_ptr<const S> sp,
const T& t)
231 return NodeTransformation::transform(sp,t);
234 static transformed_storage_type transform_storage(shared_ptr<const S> sp, T& t)
236 return NodeTransformation::transform_storage(sp,t);
239 static transformed_storage_type transform_storage(shared_ptr<const S> sp,
const T& t)
241 return NodeTransformation::transform_storage(sp,t);
248 template<
typename S,
typename T>
249 struct TransformTree<S,T,PowerNodeTag,true>
258 typedef typename LookupNodeTransformation<S,T,typename S::ImplementationTag>::type NodeTransformation;
259 typedef typename LookupNodeTransformation<typename S::ChildType,T,typename S::ChildType::ImplementationTag>::type ChildNodeTransformation;
261 typedef typename NodeTransformation::template
result<
typename TransformTree<
typename S::ChildType,
263 typename S::ChildType::NodeTag,
264 ChildNodeTransformation::recursive>::transformed_type
265 >::type transformed_type;
267 typedef typename NodeTransformation::template
result<
typename TransformTree<
typename S::ChildType,
269 typename S::ChildType::NodeTag,
270 ChildNodeTransformation::recursive>::transformed_type
271 >::storage_type transformed_storage_type;
274 static transformed_type transform(
const S& s, T& t)
277 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
278 typedef typename ChildTreeTransformation::transformed_type transformed_child;
279 const std::size_t child_count = S::CHILDREN;
280 std::array<shared_ptr<transformed_child>,child_count> children;
281 for (std::size_t k = 0; k < child_count; ++k) {
282 children[k] = ChildTreeTransformation::transform_storage(s.childStorage(k),t);
285 return NodeTransformation::transform(s,t,children);
288 static transformed_type transform(
const S& s,
const T& t)
291 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
292 typedef typename ChildTreeTransformation::transformed_type transformed_child;
293 const std::size_t child_count = S::CHILDREN;
294 std::array<shared_ptr<transformed_child>,child_count> children;
295 for (std::size_t k = 0; k < child_count; ++k) {
296 children[k] = ChildTreeTransformation::transform_storage(s.childStorage(k),t);
299 return NodeTransformation::transform(s,t,children);
303 static transformed_type transform(shared_ptr<const S> sp, T& t)
306 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
307 typedef typename ChildTreeTransformation::transformed_type transformed_child;
308 const std::size_t child_count = S::CHILDREN;
309 std::array<shared_ptr<transformed_child>,child_count> children;
310 for (std::size_t k = 0; k < child_count; ++k) {
311 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
314 return NodeTransformation::transform(sp,t,children);
317 static transformed_type transform(shared_ptr<const S> sp,
const T& t)
320 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
321 typedef typename ChildTreeTransformation::transformed_type transformed_child;
322 const std::size_t child_count = S::CHILDREN;
323 std::array<shared_ptr<transformed_child>,child_count> children;
324 for (std::size_t k = 0; k < child_count; ++k) {
325 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
328 return NodeTransformation::transform(sp,t,children);
331 static transformed_storage_type transform_storage(shared_ptr<const S> sp, T& t)
334 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
335 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
336 const std::size_t child_count = S::CHILDREN;
337 std::array<transformed_child_storage,child_count> children;
338 for (std::size_t k = 0; k < child_count; ++k) {
339 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
341 return NodeTransformation::transform_storage(sp,t,children);
344 static transformed_storage_type transform_storage(shared_ptr<const S> sp,
const T& t)
347 typedef TransformTree<typename S::ChildType,T,typename S::ChildType::NodeTag,ChildNodeTransformation::recursive> ChildTreeTransformation;
348 typedef typename ChildTreeTransformation::transformed_storage_type transformed_child_storage;
349 const std::size_t child_count = S::CHILDREN;
350 std::array<transformed_child_storage,child_count> children;
351 for (std::size_t k = 0; k < child_count; ++k) {
352 children[k] = ChildTreeTransformation::transform_storage(sp->childStorage(k),t);
354 return NodeTransformation::transform_storage(sp,t,children);
360 template<
typename S,
typename T>
361 struct TransformTree<S,T,PowerNodeTag,false>
362 :
public TransformTreeNonRecursive<S,T>
370 template<
typename S,
typename Children,
typename T>
371 struct transform_composite_node;
376 template<
typename S,
typename T,
typename... C>
377 struct transform_composite_node<S,tuple<C...>,T>
381 typedef typename S::ImplementationTag Tag;
382 typedef typename LookupNodeTransformation<S,T,Tag>::type NodeTransformation;
383 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
386 LookupNodeTransformation<C,T,typename C::ImplementationTag>::type::recursive
387 >::transformed_type...
388 >::type transformed_type;
390 typedef typename NodeTransformation::template
result<
typename TransformTree<C,
393 LookupNodeTransformation<C,T,typename C::ImplementationTag>::type::recursive
394 >::transformed_type...
395 >::storage_type transformed_storage_type;
400 template<std::
size_t i>
401 struct ChildTransformation
402 :
public TransformTree<typename S::template Child<i>::Type,
404 typename S::template Child<i>::Type::NodeTag,
405 LookupNodeTransformation<
406 typename S::template Child<i>::Type,
408 typename S::template Child<i>::Type::ImplementationTag
414 template<std::size_t... i>
415 static transformed_type transform(
const S& s, T& t, index_pack<i...> indices)
417 return NodeTransformation::transform(s,t,ChildTransformation<i>::transform_storage(s.template childStorage<i>(),t)...);
420 template<std::size_t... i>
421 static transformed_type transform(
const S& s,
const T& t, index_pack<i...> indices)
423 return NodeTransformation::transform(s,t,ChildTransformation<i>::transform_storage(s.template childStorage<i>(),t)...);
426 template<std::size_t... i>
427 static transformed_storage_type transform_storage(shared_ptr<const S> sp, T& t, index_pack<i...> indices)
429 return NodeTransformation::transform_storage(sp,t,ChildTransformation<i>::transform_storage(sp->template childStorage<i>(),t)...);
432 template<std::size_t... i>
433 static transformed_storage_type transform_storage(shared_ptr<const S> sp,
const T& t, index_pack<i...> indices)
435 return NodeTransformation::transform_storage(sp,t,ChildTransformation<i>::transform_storage(sp->template childStorage<i>(),t)...);
443 template<
typename S,
typename T>
444 struct TransformTree<S,T,CompositeNodeTag,true>
449 typedef typename S::ChildTypes ChildTypes;
451 static typename tuple_index_pack_builder<ChildTypes>::type child_indices()
458 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_type transformed_type;
459 typedef typename transform_composite_node<S,ChildTypes,T>::transformed_storage_type transformed_storage_type;
461 static transformed_type transform(
const S& s, T& t)
463 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
466 static transformed_type transform(
const S& s,
const T& t)
468 return transform_composite_node<S,ChildTypes,T>::transform(s,t,child_indices());
471 static transformed_storage_type transform_storage(shared_ptr<const S> sp, T& t)
473 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
476 static transformed_storage_type transform_storage(shared_ptr<const S> sp,
const T& t)
478 return transform_composite_node<S,ChildTypes,T>::transform_storage(sp,t,child_indices());
484 template<
typename S,
typename T>
485 struct TransformTree<S,T,CompositeNodeTag,false>
486 :
public TransformTreeNonRecursive<S,T>
496 #endif // DUNE_TYPETREE_TRANSFORMATION_HH
static transformed_storage_type transform_storage(shared_ptr< const SourceTree > sp, Transformation &t)
Definition: transformation.hh:143
type Type
Definition: transformation.hh:108
void registerNodeTransformation(SourceNode *, Transformation *, Tag *)
Register transformation descriptor to transform SourceNode with Transformation.
index_pack< 0, 1,..., n-1 > type
Result.
Definition: utility.hh:211
static transformed_type transform(const SourceTree &s, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:111
static transformed_type transform(shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Apply transformation to an existing tree s.
Definition: transformation.hh:123
Definition: accumulate_static.hh:12
Transform a TypeTree.
Definition: transformation.hh:90
static transformed_type transform(const SourceTree &s, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:117
transformed_type type
The type of the transformed tree.
Definition: transformation.hh:106
static transformed_type transform(shared_ptr< const SourceTree > sp, Transformation &t)
Apply transformation to an existing tree s.
Definition: transformation.hh:129
static const result_type result
Definition: accumulate_static.hh:109
static transformed_storage_type transform_storage(shared_ptr< const SourceTree > sp, const Transformation &t=Transformation())
Definition: transformation.hh:136