HierarchicNodeToRangeMap.hpp 1.79 KB
Newer Older
1
2
3
4
5
6
7
8
9
#pragma once

#include <utility>
#include <type_traits>

#include <dune/common/concept.hh>

#include <dune/functions/common/indexaccess.hh>

10
#include <amdis/common/Concepts.hpp>
11
12
13
14
15
16

namespace AMDiS
{
  /**
  * \brief A simple node to range map using the nested tree indices
  *
17
  * This map directly uses the tree path entries of the given
18
19
20
21
22
23
24
  * node to access the nested container.
  *
  * If the container does not provide any operator[] access,
  * it is simply forwarded for all nodes.
  */
  struct HierarchicNodeToRangeMap
  {
25
    // Specialization for ranges with operator[] access
26
    template <class Node, class TreePath, class Range,
27
      REQUIRES(Concepts::HasIndexAccess<Range, Dune::index_constant<0>>)>
28
29
    decltype(auto) operator()(const Node& node, const TreePath& treePath, Range&& y) const
    {
30
      return Dune::Functions::resolveStaticMultiIndex(y, transformTreePath(treePath));
31
32
    }

33
    // Specialization for non-container ranges
34
    template <class Node, class TreePath, class Range,
35
      REQUIRES(not Concepts::HasIndexAccess<Range, Dune::index_constant<0>>)>
36
37
38
39
    decltype(auto) operator()(const Node& node, const TreePath& treePath, Range&& y) const
    {
      return std::forward<Range>(y);
    }
40
41
42
43
44
45
46
47
48
49
50
51
52
53

  private:
#if DUNE_VERSION_GT(DUNE_FUNCTIONS,2,6)
    template <class TreePath>
    static TreePath const& transformTreePath(TreePath const& treePath)
    {
      return treePath;
    }
#else
    // NOTE: due to a bug in dune-functions <= 2.6, a hybrid-treepath can not be passed to a HierarchicNodeToRangeMap,
    // i.e. the HybridTreePath missed a size() function
    template <class TreePath>
    static auto transformTreePath(TreePath const& treePath)
    {
54
      return Ranges::apply([](auto... i) { return Dune::makeTupleVector(i...); }, treePath._data);
55
56
    }
#endif
57
58
59
  };

} // end namespace AMDiS