43 template <std::size_t Dims,
typename Type,
typename Scalar =
double,
45 std::size_t LeafSize = 4>
58 using pair_t = std::pair<coordinate_t, Type>;
91 ? KDTreeNode::NodeType::Internal
92 : KDTreeNode::NodeType::Leaf,
107 std::vector<Type>
out;
125 std::vector<pair_t>
out;
165 template <
typename OutputIt>
181 template <
typename OutputIt>
206 template <
typename Result>
210 std::vector<Result>
out;
233 template <
typename Result,
typename OutputIt>
239 const Type &
v)
mutable { i =
f(c, v); });
253 template <
typename Callable>
255 m_root->rangeSearchMapDiscard(r, std::forward<Callable>(
f));
277 if constexpr (std::is_integral_v<Scalar>) {
279 }
else if constexpr (std::is_floating_point_v<Scalar>) {
280 return std::nextafter(v, std::numeric_limits<Scalar>::max());
287 std::array<Scalar, Dims> min_v{}, max_v{};
289 for (std::size_t
i = 0;
i < Dims; ++
i) {
290 min_v[
i] = std::numeric_limits<Scalar>::max();
291 max_v[
i] = std::numeric_limits<Scalar>::lowest();
295 for (std::size_t
j = 0;
j < Dims; ++
j) {
297 max_v[
j] = std::max(max_v[j],
i->first[j]);
305 for (std::size_t
j = 0;
j < Dims; ++
j) {
334 if (
m_type == NodeType::Internal) {
342 constexpr std::size_t max_exact_median = 128;
351 if (
size() > max_exact_median) {
360 return i.first[_d] < mid;
369 return a.first[_d] < b.first[_d];
392 m_lhs = std::make_unique<KDTreeNode>(
394 lhs_size > LeafSize ? NodeType::Internal : NodeType::Leaf,
398 m_rhs = std::make_unique<KDTreeNode>(
400 rhs_size > LeafSize ? NodeType::Internal : NodeType::Leaf,
414 template <
typename Callable>
421 if (
m_type == NodeType::Internal) {
430 f(
i->first,
i->second);
441 if (
m_lhs->range() &&
r) {
442 m_lhs->rangeSearchMapDiscard(r, std::forward<Callable>(
f));
446 if (
m_rhs->range() &&
r) {
447 m_rhs->rangeSearchMapDiscard(r, std::forward<Callable>(
f));
457 f(
i->first,
i->second);