UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
iterator.hpp
1
42#ifndef UFO_CONTAINER_TREE_ITERATOR_HPP
43#define UFO_CONTAINER_TREE_ITERATOR_HPP
44
45// UFO
46#include <ufo/container/tree/index.hpp>
47
48// STL
49#include <cstddef>
50#include <iterator>
51
52namespace ufo
53{
54template <class Tree>
56{
57 private:
58 //
59 // Friends
60 //
61
62 template <class>
63 friend class TreeIterator;
64
65 private:
66 static constexpr std::size_t const BF = Tree::branchingFactor();
67
68 using Node = typename Tree::Node;
69 using offset_type = typename Tree::offset_type;
70 using depth_type = typename Tree::depth_type;
71
72 public:
73 //
74 // Tags
75 //
76
77 using iterator_category = std::forward_iterator_tag;
78 using difference_type = std::ptrdiff_t;
79 using value_type = Node;
80 using reference = value_type const&;
81 using pointer = value_type const*;
82
83 constexpr TreeIterator() = default;
84
85 TreeIterator(Tree const* tree, Node node, bool only_leaves, bool only_exists)
86 : tree_(tree)
87 , cur_(node)
88 , start_(tree->depth(node))
89 , nextNode(nextNodeFun(only_leaves, only_exists))
90 {
91 if (only_exists && !tree_->exists(cur_)) {
92 cur_ = {};
93 } else if (only_leaves && tree_->isParent(node.index)) {
94 cur_ = nextNode(*tree_, cur_, start_);
95 }
96 }
97
98 TreeIterator& operator++()
99 {
100 cur_ = nextNode(*tree_, cur_, start_);
101 return *this;
102 }
103
104 TreeIterator operator++(int)
105 {
106 TreeIterator tmp(*this);
107 ++*this;
108 return tmp;
109 }
110
111 reference operator*() const { return cur_; }
112
113 pointer operator->() const { return &cur_; }
114
115 friend bool operator==(TreeIterator const& lhs, TreeIterator const& rhs)
116 {
117 return lhs.cur_.code == rhs.cur_.code;
118 }
119
120 friend bool operator!=(TreeIterator const& lhs, TreeIterator const& rhs)
121 {
122 return !(lhs == rhs);
123 }
124
125 private:
126 [[nodiscard]] static auto nextNodeFun(bool only_leaves, bool only_exists)
127 {
128 if (only_leaves && only_exists) {
129 return &TreeIterator::next<true, true>;
130 } else if (only_leaves && !only_exists) {
131 return &TreeIterator::next<true, false>;
132 } else if (!only_leaves && only_exists) {
133 return &TreeIterator::next<false, true>;
134 } else {
135 return &TreeIterator::next<false, false>;
136 }
137 }
138
139 template <bool OnlyLeaves, bool OnlyExists>
140 [[nodiscard]] static Node next(Tree const& tree, Node node, depth_type start)
141 {
142 if constexpr (!OnlyLeaves) {
143 // Traverse down the branch
144
145 if constexpr (OnlyExists) {
146 if (tree.isParent(node.index)) {
147 node.code = node.code.firstborn();
148 node.index = tree.child(node.index, 0);
149 return node;
150 }
151 } else {
152 if (0 < node.code.depth()) {
153 node.code = node.code.firstborn();
154 if (tree.isParent(node.index)) {
155 node.index = tree.child(node.index, 0);
156 }
157 return node;
158 }
159 }
160 }
161
162 // Find next branch
163
164 while (BF - 1 <= node.code.offset()) {
165 node.code = node.code.parent();
166 }
167
168 if (start <= node.code.depth()) {
169 return Node{};
170 }
171
172 node.code = node.code.nextSibling();
173 node.index = tree.ancestor(node.index, node.code.depth());
174
175 if constexpr (OnlyExists) {
176 ++node.index.offset;
177 } else {
178 node.index.offset += node.code.depth() == tree.depth(node.index) ? 1 : 0;
179 }
180
181 if constexpr (OnlyLeaves) {
182 // Adjust index
183
184 while (tree.isParent(node.index)) {
185 node.index = tree.child(node.index, 0);
186 }
187
188 if constexpr (OnlyExists) {
189 node.code.setDepth(tree.depth(node.index));
190 } else {
191 node.code.setDepth(0);
192 }
193 }
194
195 return node;
196 }
197
198 private:
199 Tree const* tree_;
200
201 Node cur_{};
202 depth_type start_;
203
204 decltype(&TreeIterator::next<true, true>) nextNode;
205};
206} // namespace ufo
207
208#endif // UFO_CONTAINER_TREE_ITERATOR_HPP
Utilizing curiously recurring template pattern (CRTP)
Definition tree.hpp:104
bool isParent(NodeType node) const
Checks if the node is a parent (i.e., has children).
Definition tree.hpp:1308
depth_type depth() const
Returns the depth of the root node, i.e. numDepthLevels() - 1.
Definition tree.hpp:290
constexpr auto child(NodeType node, offset_type offset) const
Returns the i:th child of node.
Definition tree.hpp:1450
static constexpr offset_type branchingFactor() noexcept
Returns the branching factor of the tree (i.e., 2 = binary tree, 4 = quadtree, 8 = octree,...
Definition tree.hpp:203
All vision-related classes and functions.
Definition cloud.hpp:49