68 template <
class,
class,
class>
75 using DistanceNode =
typename Tree::DistanceNode;
76 using offset_t =
typename Tree::offset_t;
85 S(
float dist_sq, Node node,
bool returnable) noexcept
86 : dist_sq(dist_sq), node(node), returnable(returnable)
90 bool operator>(S
const& rhs)
const noexcept {
return dist_sq > rhs.dist_sq; }
93 using Queue = std::priority_queue<S, std::vector<S>, std::greater<S>>;
100 using iterator_category = std::forward_iterator_tag;
101 using difference_type = std::ptrdiff_t;
102 using value_type = DistanceNode;
103 using reference = value_type
const&;
104 using pointer = value_type
const*;
109 Geometry
const& geometry,
float epsilon,
bool only_exists,
114 , epsilon_sq_(epsilon * epsilon)
115 , only_exists_(only_exists)
116 , early_stopping_(early_stopping)
118 Filter::init(pred_, *t_);
120 if (only_exists_ && !t_->exists(node)) {
125 if (returnable(node)) {
126 queue_.emplace(dist_sq, node,
true);
128 if (!early_stopping_ && traversable(node)) {
129 queue_.emplace(dist_sq + epsilon_sq_, node,
false);
131 }
else if (traversable(node)) {
132 queue_.emplace(dist_sq + epsilon_sq_, node,
false);
140 template <
class Predicate2,
class Geometry2>
145 , query_(other.query_)
146 , epsilon_sq_(other.epsilon_sq_)
147 , queue_(other.queue_)
149 , only_exists_(other.only_exists_)
150 , early_stopping_(other.early_stopping_)
168 reference operator*()
const {
return ret_; }
170 pointer operator->()
const {
return &ret_; }
172 template <
class Predicate2,
class Geometry2>
175 return ret_ == other.ret_;
178 template <
class Predicate2,
class Geometry2>
181 return !(*
this == other);
185 [[nodiscard]]
bool returnable(Node
const& node)
const
187 return Filter::returnable(pred_, *t_, node);
190 [[nodiscard]]
bool returnable(S
const& s)
const {
return s.returnable; }
192 [[nodiscard]]
bool traversable(Node
const& node)
const
195 Filter::traversable(pred_, *t_, node);
198 [[nodiscard]]
bool exists(Node
const& node)
const
200 return only_exists_ || t_->code(node.index) == node.code;
203 [[nodiscard]] Node sibling(Node
const& node, offset_t sibling_index)
const
205 return Node(t_->sibling(node.code, sibling_index),
206 exists(node) ? t_->sibling(node.index, sibling_index) : node.index);
209 [[nodiscard]] Node child(Node
const& node, offset_t child_index)
const
212 t_->
child(node.code, child_index),
213 t_->
isParent(node.index) ? t_->
child(node.index, child_index) : node.index);
216 [[nodiscard]] Node parent(Node
const& node)
const
218 return Node(t_->parent(node.code),
219 exists(node) ? t_->parent(node.index) : node.index);
222 [[nodiscard]] offset_t offset(Node
const& node)
const {
return node.code.
offset(); }
226 while (!queue_.empty()) {
227 S cur = queue_.top();
228 if (returnable(cur)) {
229 ret_ = DistanceNode(cur.node, std::sqrt(cur.dist_sq));
235 Node node = child(cur.node, 0);
236 for (offset_t i{}; BF > i; ++i) {
237 node = sibling(node, i);
240 if (returnable(node)) {
241 queue_.emplace(dist_sq, node,
true);
243 if (!early_stopping_ && traversable(node)) {
244 queue_.emplace(dist_sq + epsilon_sq_, node,
false);
246 }
else if (traversable(node)) {
247 queue_.emplace(dist_sq + epsilon_sq_, node,
false);
265 bool early_stopping_{};