66class TreeMap :
protected Tree<TreeMap<Dim, T>, Dim, TreeMapBlock<T>>
75 std::is_same_v<typename LeafBlock::value_type, typename InnerBlock::value_type>);
76 static_assert(std::is_same_v<
typename LeafBlock::container_type,
77 typename InnerBlock::container_type>);
86 template <
class Geometry, pred::SpatialTag Tag,
bool Negated>
87 friend class pred::Spatial;
105 using coord_type =
typename Base::coord_type;
106 using depth_type =
typename Base::depth_type;
107 using offset_type =
typename Base::offset_type;
108 using length_type =
typename Base::length_type;
109 using pos_type =
typename Base::pos_type;
112 using value_type =
typename LeafBlock::value_type;
113 using mapped_type = T;
114 using reference = value_type&;
115 using const_reference = value_type
const&;
116 using pointer = value_type*;
117 using const_pointer = value_type
const*;
118 using size_type = std::size_t;
119 using difference_type = std::ptrdiff_t;
127 template <
class Predicate>
129 template <
class Predicate>
135 template <
class Geometry>
137 template <
class Geometry>
143 template <
class Predicate,
class Geometry>
146 template <
class Predicate,
class Geometry>
155 template <
class Predicate>
156 using Query = IteratorWrapper<query_iterator_pred<Predicate>,
query_iterator>;
157 template <
class Predicate>
161 template <
class Geometry>
162 using Nearest = IteratorWrapper<nearest_iterator_geom<Geometry>,
nearest_iterator>;
163 template <
class Geometry>
167 template <
class Predicate,
class Geometry>
169 IteratorWrapper<query_nearest_iterator_pred_geom<Predicate, Geometry>,
171 template <
class Predicate,
class Geometry>
172 using ConstQueryNearest =
173 IteratorWrapper<const_query_nearest_iterator_pred_geom<Predicate, Geometry>,
180 template <
bool, std::
size_t,
class>
183 template <
bool, std::
size_t,
class,
class>
186 template <
bool, std::
size_t,
class,
class>
189 template <
bool, std::
size_t,
class,
class,
class>
193 using container_type =
typename LeafBlock::container_type;
202 TreeMap(Length leaf_node_length = Length(0.1),
203 depth_type num_depth_levels = std::min(depth_type(17),
205 :
Base(leaf_node_length, num_depth_levels)
209 TreeMap(length_type leaf_node_length,
210 depth_type num_depth_levels = std::min(depth_type(17),
212 :
TreeMap(Length(leaf_node_length), num_depth_levels)
216 template <
class InputIt>
217 TreeMap(InputIt first, InputIt last, length_type leaf_node_length = length_type(0.1),
218 depth_type num_depth_levels = std::min(depth_type(17),
220 :
TreeMap(leaf_node_length, num_depth_levels)
225 TreeMap(std::initializer_list<value_type> init,
226 length_type leaf_node_length = length_type(0.1),
227 depth_type num_depth_levels = std::min(depth_type(17),
229 :
TreeMap(init.begin(), init.end(), leaf_node_length, num_depth_levels)
233 template <
class Range>
234 TreeMap(
Range const& range, length_type leaf_node_length = length_type(0.1),
235 depth_type num_depth_levels = std::min(depth_type(17),
237 :
TreeMap(std::begin(range), std::end(range), leaf_node_length, num_depth_levels)
290 template <
class Predicate>
296 template <
class Predicate>
298 Predicate
const& pred)
const
304 template <
class Predicate>
306 Predicate
const& pred)
const
308 return beginQuery(pred);
323 template <
class Geometry>
325 float epsilon = 0.0f)
330 template <
class Geometry>
332 Geometry
const& query,
float epsilon = 0.0f)
const
338 template <
class Geometry>
340 Geometry
const& query,
float epsilon = 0.0f)
const
342 return beginNearest(query, epsilon);
360 template <
class Predicate,
class Geometry>
362 Predicate
const& pred, Geometry
const& query,
float epsilon = 0.0f)
365 pred, query, epsilon);
368 template <
class Predicate,
class Geometry>
370 beginQueryNearest(Predicate
const& pred, Geometry
const& query,
371 float epsilon = 0.0f)
const
377 template <
class Predicate,
class Geometry>
379 cbeginQueryNearest(Predicate
const& pred, Geometry
const& query,
380 float epsilon = 0.0f)
const
382 return beginQueryNearest(pred, query, epsilon);
397 return endQueryNearest();
411 [[nodiscard]]
bool empty() const noexcept {
return 0 ==
size(); }
418 [[nodiscard]] size_type
size() const noexcept {
return size_; }
444 template <
class... Args>
445 void emplace(Point point, Args&&... args)
447 insert(value_type(point, T(std::forward<Args>(args)...)));
450 void insert(value_type
const& value)
452 Index
node = Base::create(value.first);
456 void insert(value_type&& value)
458 Index
node = Base::create(value.first);
459 insert(
node, std::move(value));
462 template <
class InputIt>
463 void insert(InputIt first, InputIt last)
465 std::vector<Point> points;
467 std::transform(first, last, std::back_inserter(points),
468 [](
auto const& v) {
return v.first; });
470 auto nodes = Base::create(points.begin(), points.end());
472 for (std::size_t i{}; first != last; ++i, ++first) {
473 insert(nodes[i], *first);
478 class ExecutionPolicy,
class RandomIt,
479 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
480 void insert(ExecutionPolicy&& policy, RandomIt first, RandomIt last)
482 std::vector<Point> points(std::distance(first, last));
484 if constexpr (execution::is_stl_v<ExecutionPolicy>) {
485 std::transform(execution::toSTL(policy), first, last, points.begin(),
486 [](
auto const& v) { return v.first; });
488#if defined(UFO_PAR_GCD)
489 else if constexpr (execution::is_gcd_v<ExecutionPolicy>) {
491 static_assert(dependent_false_v<ExecutionPolicy>,
492 "insert not implemented for that execution policy");
495#if defined(UFO_PAR_TBB)
496 else if constexpr (execution::is_tbb_v<ExecutionPolicy>) {
498 static_assert(dependent_false_v<ExecutionPolicy>,
499 "insert not implemented for that execution policy");
502 else if constexpr (execution::is_omp_v<ExecutionPolicy>) {
503 if constexpr (execution::is_seq_v<ExecutionPolicy>) {
504 for (std::size_t i = 0; points.size() > i; ++i) {
505 points[i] = first[i].first;
507 }
else if constexpr (execution::is_unseq_v<ExecutionPolicy>) {
509 for (std::size_t i = 0; points.size() > i; ++i) {
510 points[i] = first[i].first;
512 }
else if constexpr (execution::is_par_v<ExecutionPolicy>) {
513#pragma omp parallel for
514 for (std::size_t i = 0; points.size() > i; ++i) {
515 points[i] = first[i].first;
517 }
else if constexpr (execution::is_par_unseq_v<ExecutionPolicy>) {
518#pragma omp parallel for simd
519 for (std::size_t i = 0; points.size() > i; ++i) {
520 points[i] = first[i].first;
524 static_assert(dependent_false_v<ExecutionPolicy>,
525 "Not implemented for the execution policy");
529 Base::create(std::forward<ExecutionPolicy>(policy), points.begin(), points.end());
531 for (std::size_t i{}; first != last; ++i, ++first) {
532 insert(nodes[i], *first);
536 void insert(std::initializer_list<value_type> ilist)
538 insert(ilist.begin(), ilist.end());
542 class ExecutionPolicy,
543 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
544 void insert(ExecutionPolicy&& policy, std::initializer_list<value_type> ilist)
546 insert(std::forward<ExecutionPolicy>(policy), ilist.begin(), ilist.end());
549 template <
class Range>
550 void insert(Range
const& r)
554 insert(begin(r), end(r));
558 class ExecutionPolicy,
class Range,
559 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>,
bool> =
true>
560 void insert(ExecutionPolicy&& policy, Range
const& r)
564 insert(std::forward<ExecutionPolicy>(policy), begin(r), end(r));
567 size_type erase(value_type
const& value)
575 auto& v = values(
node);
576 size_type num_removed = v.size();
577 v.remove_if([&value](
auto const& x) {
578 return x.first == value.first && x.second == value.second;
580 num_removed -= v.size();
582 size_ -= num_removed;
584 erasePropagate(
node);
589 iterator erase(iterator pos)
591 auto it = pos.iterator();
597 iterator erase(const_iterator pos)
599 auto it = pos.iterator();
602 return iterator(pos);
605 template <
class Predicate>
606 query_iterator_pred<Predicate> erase(query_iterator_pred<Predicate> pos)
608 auto it = pos.iterator();
614 template <
class Predicate>
615 query_iterator_pred<Predicate> erase(const_query_iterator_pred<Predicate> pos)
617 auto it = pos.iterator();
620 return query_iterator_pred<Predicate>(pos);
623 template <
class Geometry>
624 nearest_iterator_geom<Geometry> erase(nearest_iterator_geom<Geometry> pos)
626 auto it = pos.iterator();
632 template <
class Geometry>
633 nearest_iterator_geom<Geometry> erase(const_nearest_iterator_geom<Geometry> pos)
635 auto it = pos.iterator();
638 return nearest_iterator_geom<Geometry>(pos);
641 template <
class Predicate,
class Geometry>
642 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
643 query_nearest_iterator_pred_geom<Predicate, Geometry> pos)
645 auto it = pos.iterator();
651 template <
class Predicate,
class Geometry>
652 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
653 const_query_nearest_iterator_pred_geom<Predicate, Geometry> pos)
655 auto it = pos.iterator();
658 return query_nearest_iterator_pred_geom<Predicate, Geometry>(pos);
661 iterator erase(iterator first, iterator last)
663 while (last != first) {
664 auto it = first.iterator();
671 iterator erase(const_iterator first, const_iterator last)
673 while (last != first) {
674 auto it = first.iterator();
678 return iterator(first);
681 template <
class Predicate1,
class Predicate2>
682 query_iterator_pred<Predicate1> erase(query_iterator_pred<Predicate1> first,
683 query_iterator_pred<Predicate2> last)
685 while (last != first) {
686 auto it = first.iterator();
693 template <
class Predicate1,
class Predicate2>
694 query_iterator_pred<Predicate1> erase(const_query_iterator_pred<Predicate1> first,
695 const_query_iterator_pred<Predicate2> last)
697 while (last != first) {
698 auto it = first.iterator();
702 return query_iterator_pred<Predicate1>(first);
705 template <
class Predicate>
706 query_iterator_pred<Predicate> erase(Query<Predicate> query)
708 return erase(query.begin(), query.end());
711 template <
class Predicate>
712 query_iterator_pred<Predicate> erase(ConstQuery<Predicate> query)
714 return erase(query.begin(), query.end());
717 template <
class Geometry1,
class Geometry2>
718 nearest_iterator_geom<Geometry1> erase(nearest_iterator_geom<Geometry1> first,
719 nearest_iterator_geom<Geometry2> last)
721 while (last != first) {
722 auto it = first.iterator();
729 template <
class Geometry1,
class Geometry2>
730 nearest_iterator_geom<Geometry1> erase(const_nearest_iterator_geom<Geometry1> first,
731 const_nearest_iterator_geom<Geometry2> last)
733 while (last != first) {
734 auto it = first.iterator();
738 return nearest_iterator_geom<Geometry1>(first);
741 template <
class Predicate1,
class Geometry1,
class Predicate2,
class Geometry2>
742 query_nearest_iterator_pred_geom<Predicate1, Geometry1> erase(
743 query_nearest_iterator_pred_geom<Predicate1, Geometry1> first,
744 query_nearest_iterator_pred_geom<Predicate2, Geometry2> last)
746 while (last != first) {
747 auto it = first.iterator();
754 template <
class Predicate1,
class Geometry1,
class Predicate2,
class Geometry2>
755 query_nearest_iterator_pred_geom<Predicate1, Geometry1> erase(
756 const_query_nearest_iterator_pred_geom<Predicate1, Geometry1> first,
757 const_query_nearest_iterator_pred_geom<Predicate2, Geometry2> last)
759 while (last != first) {
760 auto it = first.iterator();
764 return query_nearest_iterator_pred_geom<Predicate1, Geometry1>(first);
767 template <
class Predicate,
class Geometry>
768 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
769 QueryNearest<Predicate, Geometry> query)
771 return erase(query.begin(), query.end());
774 template <
class Predicate,
class Geometry>
775 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
776 ConstQueryNearest<Predicate, Geometry> query)
778 return erase(query.begin(), query.end());
781 size_type erase(Point point)
789 auto& v = values(
node);
790 size_type num_removed = v.size();
791 v.remove_if([point](
auto const& x) {
return x.first == point; });
792 num_removed -= v.size();
794 size_ -= num_removed;
796 erasePropagate(
node);
808 std::swap(size_, other.size_);
809 std::swap(
static_cast<Base&
>(*
this),
static_cast<Base&
>(other));
825 [[nodiscard]] size_type
count(Point point)
const
828 return std::count_if(v.begin(), v.end(),
829 [point](
auto const& x) { return x.first == point; });
842 return std::end(v) != std::find_if(v.begin(), v.end(), [point](
auto const& x) {
843 return x.first == point;
847 template <
class Predicate>
848 [[nodiscard]] Query<Predicate> query(Predicate
const& pred)
850 return Query<Predicate>(beginQuery(pred), endQuery());
853 template <
class Predicate>
854 [[nodiscard]] ConstQuery<Predicate> query(Predicate
const& pred)
const
856 return ConstQuery<Predicate>(beginQuery(pred), endQuery());
859 template <
class Geometry>
860 [[nodiscard]] Nearest<Geometry> nearest(Geometry
const& query,
float epsilon = 0.0f)
862 return Nearest<Geometry>(beginNearest(query, epsilon), endNearest());
865 template <
class Geometry>
866 [[nodiscard]] ConstNearest<Geometry> nearest(Geometry
const& query,
867 float epsilon = 0.0f)
const
869 return ConstNearest<Geometry>(beginNearest(query, epsilon), endNearest());
872 template <
class Predicate,
class Geometry>
873 [[nodiscard]] QueryNearest<Predicate, Geometry> queryNearest(Predicate
const& pred,
874 Geometry
const& query,
875 float epsilon = 0.0f)
877 return QueryNearest<Predicate, Geometry>(beginQueryNearest(pred, query, epsilon),
881 template <
class Predicate,
class Geometry>
882 [[nodiscard]] ConstQueryNearest<Predicate, Geometry> queryNearest(
883 Predicate
const& pred, Geometry
const& query,
float epsilon = 0.0f)
const
885 return ConstQueryNearest<Predicate, Geometry>(beginQueryNearest(pred, query, epsilon),
889 template <
class Geometry>
890 [[nodiscard]]
float nearestDistance(
891 Geometry
const& query,
float max_distance = std::numeric_limits<float>::infinity(),
892 float epsilon = 0.0f,
893 NearestSearchAlgorithm search_alg = NearestSearchAlgorithm::DEPTH_FIRST)
const
895 float max_distance_sq = max_distance * max_distance;
899 [
this, &query](Index
node) {
900 float dist_sq = std::numeric_limits<float>::infinity();
901 for (
auto e : values(
node)) {
907 max_distance_sq, epsilon * epsilon)
910 return max_distance_sq <= dist_sq ? max_distance : std::sqrt(dist_sq);
913 template <
class Geometry>
914 [[nodiscard]] std::pair<value_type*, float> nearestPoint(
915 Geometry
const& query,
float max_distance = std::numeric_limits<float>::infinity(),
916 float epsilon = 0.0f,
917 NearestSearchAlgorithm search_alg = NearestSearchAlgorithm::DEPTH_FIRST)
919 float max_distance_sq = max_distance * max_distance;
920 auto [dist_sq,
node] = Base::nearest(
922 [
this, &query](Index
node) {
923 float dist_sq = std::numeric_limits<float>::infinity();
924 for (
auto e : values(
node)) {
930 max_distance_sq, epsilon * epsilon);
932 value_type* value =
nullptr;
934 for (
auto& e : values(
node)) {
938 return {value, max_distance_sq <= dist_sq ? max_distance : std::sqrt(dist_sq)};
941 template <
class Geometry>
942 [[nodiscard]] std::pair<value_type const*, float> nearestPoint(
943 Geometry
const& query,
float max_distance = std::numeric_limits<float>::infinity(),
944 float epsilon = 0.0f,
945 NearestSearchAlgorithm search_alg = NearestSearchAlgorithm::DEPTH_FIRST)
const
947 float max_distance_sq = max_distance * max_distance;
948 auto [dist_sq,
node] = Base::nearest(
950 [
this, &query](Index
node) {
951 float dist_sq = std::numeric_limits<float>::infinity();
952 for (
auto e : values(
node)) {
958 max_distance_sq, epsilon * epsilon);
960 value_type
const* value =
nullptr;
962 for (
auto const& e : values(
node)) {
966 return {value, max_distance_sq <= dist_sq ? max_distance : std::sqrt(dist_sq)};
982 template <
class NodeType,
983 std::enable_if_t<Base::template is_node_type_v<NodeType>,
bool> =
true>
987 return Base::treeBlock(n).bounds[n.offset];
997 template <
class NodeType,
998 std::enable_if_t<Base::template is_node_type_v<NodeType>,
bool> =
true>
1002 return Base::treeBlock(n).bounds[n.offset];
1011 template <std::
size_t D,
class U>
1014 template <std::
size_t D,
class U>
1024 void onInitRoot() {}
1026 void onInitChildren(Index , pos_type ) {}
1028 void onPruneChildren(Index , pos_type ) {}
1053 void insert(Index
node, value_type
const& value)
1055 Point p = value.first;
1056 values(
node).push_back(value);
1059 insertPropagate(
node, p);
1062 void insert(Index
node, value_type&& value)
1064 Point p = value.first;
1065 values(
node).push_back(std::move(value));
1068 insertPropagate(
node, p);
1071 void insertPropagate(Index
node, Point p)
1091 void erase(
typename container_type::const_iterator it)
1099 auto& v = values(
node);
1103 erasePropagate(
node);
1106 void erasePropagate(Index
node)
1108 Point
min(std::numeric_limits<typename Point::value_type>::max());
1109 Point
max(std::numeric_limits<typename Point::value_type>::lowest());
1110 for (
auto const& [p, _] : values(
node)) {
1117 if (Base::isRoot(
node)) {
1122 auto child_block =
node.pos;
1128 for (std::size_t i = 1; Base::BF > i; ++i) {
1134 child_block =
node.pos;
1141 for (std::size_t i = 1; Base::BF > i; ++i) {
1155 [[nodiscard]]
auto& values(pos_type
block) {
return Base::treeBlock(
block).values; }
1157 [[nodiscard]]
auto const& values(pos_type
block)
const
1159 return Base::treeBlock(
block).values;
1162 [[nodiscard]]
auto& values(Index
node)
1164 return Base::treeBlock(
node).values[
node.offset];
1167 [[nodiscard]]
auto const& values(Index
node)
const
1169 return Base::treeBlock(
node).values[
node.offset];
1182 return Base::treeBlock(
node).bounds[
node.offset].min;
1195 return Base::treeBlock(
node).bounds[
node.offset].min;
1208 return Base::treeBlock(
node).bounds[
node.offset].max;
1221 return Base::treeBlock(
node).bounds[
node.offset].max;