Visitor.hpp 3.51 KB
Newer Older
1
2
3
#pragma once

#include <dune/typetree/visitor.hh>
4
5
#include <amdis/common/Mpl.hpp>
#include <amdis/utility/Traversal.hpp>
6
7
8

namespace AMDiS
{
9
10
  // from dune-typetree merge-request !2
  namespace Impl
11
  {
12
13
14
    template <class PreFunc, class LeafFunc, class PostFunc>
    class CallbackVisitor
        : public Dune::TypeTree::TreeVisitor
15
    {
16
17
18
19
20
21
22
23
24
    public:
      CallbackVisitor(PreFunc& preFunc, LeafFunc& leafFunc, PostFunc& postFunc)
        : preFunc_(preFunc)
        , leafFunc_(leafFunc)
        , postFunc_(postFunc)
      {}

      template <typename Node, typename TreePath>
      void pre(Node&& node, TreePath treePath)
25
      {
26
        preFunc_(node, treePath);
27
      }
28

29
30
      template <typename Node, typename TreePath>
      void leaf(Node&& node, TreePath treePath)
31
      {
32
        leafFunc_(node, treePath);
33
34
      }

35
36
      template <typename Node, typename TreePath>
      void post(Node&& node, TreePath treePath)
37
      {
38
        postFunc_(node, treePath);
39
40
      }

41
42
43
44
45
    private:
      PreFunc& preFunc_;
      LeafFunc& leafFunc_;
      PostFunc& postFunc_;
    };
46

47
48
    template <class PreFunc, class LeafFunc, class PostFunc>
    auto callbackVisitor(PreFunc& preFunc, LeafFunc& leafFunc, PostFunc& postFunc)
49
    {
50
      return CallbackVisitor<PreFunc, LeafFunc, PostFunc>(preFunc, leafFunc, postFunc);
51
52
    }

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  } // namespace Impl


  /**
    * \brief Traverse tree and visit each node
    *
    * All passed callback functions are called with the
    * node and corresponding treepath as arguments.
    *
    * \param tree The tree to traverse
    * \param preFunc This function is called for each inner node before visiting its children
    * \param leafFunc This function is called for each leaf node
    * \param postFunc This function is called for each inner node after visiting its children
    */
  template <class Tree, class PreFunc, class LeafFunc, class PostFunc>
  void forEachNode(Tree&& tree, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
  {
70
    traverseTree(tree, Impl::callbackVisitor(preFunc, leafFunc, postFunc));
71
  }
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  /**
    * \brief Traverse tree and visit each node
    *
    * All passed callback functions are called with the
    * node and corresponding treepath as arguments.
    *
    * \param tree The tree to traverse
    * \param innerFunc This function is called for each inner node before visiting its children
    * \param leafFunc This function is called for each leaf node
    */
  template <class Tree, class InnerFunc, class LeafFunc>
  void forEachNode(Tree&& tree, InnerFunc&& innerFunc, LeafFunc&& leafFunc)
  {
    auto nop = [](auto&&... args) {};
    forEachNode(tree, innerFunc, leafFunc, nop);
  }
89

90
91
92
93
94
95
96
97
98
99
100
  /**
    * \brief Traverse tree and visit each node
    *
    * The passed callback function is called with the
    * node and corresponding treepath as arguments.
    *
    * \param tree The tree to traverse
    * \param nodeFunc This function is called for each node
    */
  template <class Tree, class NodeFunc>
  void forEachNode(Tree&& tree, NodeFunc&& nodeFunc)
101
  {
102
    forEachNode(tree, nodeFunc, nodeFunc);
103
104
  }

105
106
107
108
109
110
111
112
113
114
115
  /**
    * \brief Traverse tree and visit each leaf node
    *
    * The passed callback function is called with the
    * node and corresponding treepath as arguments.
    *
    * \param tree The tree to traverse
    * \param leafFunc This function is called for each leaf node
    */
  template <class Tree, class LeafFunc>
  void forEachLeafNode(Tree&& tree, LeafFunc&& leafFunc)
116
  {
117
118
    auto nop = [](auto&&... args) {};
    forEachNode(tree, nop, leafFunc, nop);
119
120
121
  }

} // end namespace AMDiS