symbolic
depth_first_search.h
1 
10 #ifndef SYMBOLIC_PLANNING_DEPTH_FIRST_SEARCH_H_
11 #define SYMBOLIC_PLANNING_DEPTH_FIRST_SEARCH_H_
12 
13 #include <cstddef> // ptrdiff_t
14 #include <iterator> // std::input_iterator_tag
15 #include <stack> // std::stack
16 #include <vector> // std::vector
17 #include <utility> // std::pair
18 
19 namespace symbolic {
20 
21 template<typename NodeT>
23 
24  public:
25 
26  class iterator;
27 
28  DepthFirstSearch(const NodeT& root, size_t max_depth) : kMaxDepth(max_depth), root_(root) {}
29 
30  iterator begin() { iterator it(root_, kMaxDepth); return ++it; }
31  iterator end() { return iterator(); }
32 
33  private:
34 
35  const size_t kMaxDepth;
36 
37  const NodeT& root_;
38 
39 };
40 
41 template<typename NodeT>
42 class DepthFirstSearch<NodeT>::iterator {
43 
44  public:
45 
46  using iterator_category = std::input_iterator_tag;
47  using value_type = std::vector<NodeT>;
48  using difference_type = ptrdiff_t;
49  using pointer = const value_type*;
50  using reference = const value_type&;
51 
52  iterator() = default;
53  iterator(const NodeT& root, size_t max_depth)
54  : stack_({{root, std::vector<NodeT>()}}), kMaxDepth(max_depth) {}
55 
56  iterator& operator++();
57  bool operator==(const iterator& other) const { return stack_.empty() && other.stack_.empty(); }
58  bool operator!=(const iterator& other) const { return !(*this == other); }
59  reference operator*() const { return ancestors_; }
60 
61  private:
62 
63  const size_t kMaxDepth = 0;
64 
65  std::stack<std::pair<NodeT, std::vector<NodeT>>> stack_;
66  std::vector<NodeT> ancestors_;
67 
68 };
69 
70 template<typename NodeT>
72  while (!stack_.empty()) {
73  std::pair<NodeT, std::vector<NodeT>>& top = stack_.top();
74 
75  // Take ancestors list and append current node
76  ancestors_.swap(top.second);
77  ancestors_.push_back(std::move(top.first));
78  stack_.pop();
79 
80  // Return if node evaluates to true
81  const NodeT& node = ancestors_.back();
82  if (node) break;
83 
84  // Skip children if max depth has been reached
85  if (ancestors_.size() > kMaxDepth) continue;
86 
87  // Add node's children to stack
88  // TODO(tmigimatsu): iterate backwards so children get visited in order
89  for (const NodeT& child : node) {
90  stack_.emplace(child, ancestors_);
91  }
92  }
93  return *this;
94 }
95 
96 } // namespace symbolic
97 
98 #endif // SYMBOLIC_PLANNING_DEPTH_FIRST_SEARCH_H_
symbolic::DepthFirstSearch::iterator
Definition: depth_first_search.h:42
symbolic
Definition: action.cc:329
symbolic::DepthFirstSearch
Definition: depth_first_search.h:22