Project
Loading...
Searching...
No Matches
DataMatcherWalker.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_DATAMATCHERWALKER_H_
12#define O2_FRAMEWORK_DATAMATCHERWALKER_H_
13
16
18{
19
21 struct EnterNode {
23 };
24 struct ExitNode {
26 };
27 struct EnterLeft {
28 };
29 struct ExitLeft {
30 };
31 struct EnterRight {
32 };
33 struct ExitRight {
34 };
35};
36
37enum ChildAction : int {
41 VisitBoth = 3
42};
43
44using EdgeAction = std::variant<EdgeActions::EnterNode, EdgeActions::ExitNode>;
45
49
50 // Deep-first algorithm
51 // @a top is the toplevel node in the tree.
52 // @a edgeWalker is a visitor for an EdgeAction
53 // @a leafWalker is a visitor for the DataDescriptorMatcher node
54 template <typename EDGEWALKER, typename LEAFWALKER>
55 static void walk(DataDescriptorMatcher const& top,
56 EDGEWALKER edgeWalker,
57 LEAFWALKER leafWalker)
58 {
59 std::vector<EdgeAction> matchers;
60 matchers.push_back(EdgeActions::EnterNode{&top});
61
62 while (matchers.empty() == false) {
63 EdgeAction action = matchers.back();
64 matchers.pop_back();
65 ChildAction childrenVisitor = std::visit(overloaded{
66 [&matchers, &edgeWalker](EdgeActions::EnterNode action) {
67 matchers.push_back(EdgeActions::ExitNode{action.node});
68 return edgeWalker(action);
69 },
70 [&edgeWalker](EdgeActions::ExitNode action) {
71 edgeWalker(action);
73 }},
74 action);
75
76 if (childrenVisitor & ChildAction::VisitRight) {
77 auto node = std::visit([](auto action) { return action.node; }, action);
78
79 std::visit(overloaded{
80 [&matchers](std::unique_ptr<DataDescriptorMatcher> const& matcher) {
81 matchers.push_back(EdgeActions::EnterNode{matcher.get()});
82 },
83 [edgeWalker, leafWalker](auto const& leaf) {
84 edgeWalker(EdgeActions::EnterRight{});
85 leafWalker(leaf);
86 edgeWalker(EdgeActions::ExitRight{});
87 }},
88 node->getRight());
89 }
90
91 if (childrenVisitor & ChildAction::VisitLeft) {
92 auto node = std::visit([](auto action) { return action.node; }, action);
93
94 std::visit(overloaded{
95 [&matchers](std::unique_ptr<DataDescriptorMatcher> const& matcher) {
96 matchers.push_back(EdgeActions::EnterNode{matcher.get()});
97 },
98 [edgeWalker, leafWalker](auto const& leaf) {
99 edgeWalker(EdgeActions::EnterLeft{});
100 leafWalker(leaf);
101 edgeWalker(EdgeActions::ExitLeft{});
102 }},
103 node->getLeft());
104 }
105 }
106 }
107};
108
109} // namespace o2::framework::data_matcher
110
111#endif // O2_FRAMEWORK_DATAMATCHERWALKER_H_
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
std::variant< EdgeActions::EnterNode, EdgeActions::ExitNode > EdgeAction
static void walk(DataDescriptorMatcher const &top, EDGEWALKER edgeWalker, LEAFWALKER leafWalker)
From https://en.cppreference.com/w/cpp/utility/variant/visit.