66 :
protected Tree<TreeSet<Dim>, Dim, TreeSetBlock<Dim, std::size_t(1) << Dim>>
69 using Block = TreeSetBlock<Dim, std::size_t(1) << Dim>;
70 using Base = Tree<TreeSet, Dim, Block>;
79 friend typename Base::const_iterator;
81 template <class Geometry, pred::SpatialTag Tag, bool Negated>
82 friend class pred::Spatial;
92 using Index = typename Base::Index;
93 using Node = typename Base::Node;
94 using Code = typename Base::Code;
95 using Key = typename Base::Key;
96 using Point = typename Base::Point;
97 using Coord = typename Base::Coord;
98 using Bounds = typename Base::Bounds;
99 using Length = typename Base::Length;
100 using coord_t = typename Base::coord_t;
101 using depth_t = typename Base::depth_t;
102 using offset_t = typename Base::offset_t;
103 using length_t = typename Base::length_t;
104 using pos_t = typename Base::pos_t;
107 using value_type = typename Block::value_type;
108 using reference = value_type&;
109 using const_reference = value_type const&;
110 using pointer = value_type*;
111 using const_pointer = value_type const*;
112 using size_type = std::size_t;
113 using difference_type = std::ptrdiff_t;
118 using const_iterator = TreeSetIterator<true, Dim>;
119 using iterator = const_iterator;
121 template <class Predicate>
122 using const_query_iterator_pred = TreeSetQueryIterator<true, Dim, Predicate>;
123 template <class Predicate>
124 using query_iterator_pred = const_query_iterator_pred<Predicate>;
126 using const_query_iterator = const_query_iterator_pred<pred::Predicate<TreeSet>>;
127 using query_iterator = const_query_iterator;
129 template <class Geometry>
130 using const_nearest_iterator_geom = TreeSetNearestIterator<true, Dim, Geometry>;
131 template <class Geometry>
132 using nearest_iterator_geom = const_nearest_iterator_geom<Geometry>;
134 using const_nearest_iterator = const_nearest_iterator_geom<DynamicGeometry>;
135 using nearest_iterator = const_nearest_iterator;
137 template <class Predicate, class Geometry>
138 using const_query_nearest_iterator_pred_geom =
139 TreeSetQueryNearestIterator<true, Dim, Predicate, Geometry>;
140 template <class Predicate, class Geometry>
141 using query_nearest_iterator_pred_geom =
142 const_query_nearest_iterator_pred_geom<Predicate, Geometry>;
144 using const_query_nearest_iterator =
145 const_query_nearest_iterator_pred_geom<pred::Predicate<TreeSet>, DynamicGeometry>;
146 using query_nearest_iterator = const_query_nearest_iterator;
148 template <class Predicate>
150 IteratorWrapper<const_query_iterator_pred<Predicate>, const_query_iterator>;
151 template <class Predicate>
152 using Query = ConstQuery<Predicate>;
154 template <class Geometry>
156 IteratorWrapper<const_nearest_iterator_geom<Geometry>, const_nearest_iterator>;
157 template <class Geometry>
158 using Nearest = ConstNearest<Geometry>;
160 template <class Predicate, class Geometry>
161 using ConstQueryNearest =
162 IteratorWrapper<const_query_nearest_iterator_pred_geom<Predicate, Geometry>,
163 const_query_nearest_iterator>;
164 template <class Predicate, class Geometry>
165 using QueryNearest = ConstQueryNearest<Predicate, Geometry>;
171 template <bool, std::size_t>
172 friend class TreeSetIterator;
174 template <bool, std::size_t, class>
175 friend class TreeSetQueryIterator;
177 template <bool, std::size_t, class>
178 friend class TreeSetNearestIterator;
180 template <bool, std::size_t, class, class>
181 friend class TreeSetQueryNearestIterator;
184 using container_type = typename Block::container_type;
193 TreeSet(Length leaf_node_length = Length(0.1),
194 depth_t num_depth_levels = std::min(depth_t(17), Base::maxNumDepthLevels()))
195 : Base(leaf_node_length, num_depth_levels)
199 TreeSet(length_t leaf_node_length,
200 depth_t num_depth_levels = std::min(depth_t(17), Base::maxNumDepthLevels()))
201 : TreeSet(Length(leaf_node_length), num_depth_levels)
205 template <class InputIt>
206 TreeSet(InputIt first, InputIt last, length_t leaf_node_length = length_t(0.1),
207 depth_t num_depth_levels = std::min(depth_t(17), Base::maxNumDepthLevels()))
208 : TreeSet(leaf_node_length, num_depth_levels)
213 TreeSet(std::initializer_list<value_type> init,
214 length_t leaf_node_length = length_t(0.1),
215 depth_t num_depth_levels = std::min(depth_t(17), Base::maxNumDepthLevels()))
216 : TreeSet(init.begin(), init.end(), leaf_node_length, num_depth_levels)
220 template <class Range>
221 TreeSet(Range const& range, length_t leaf_node_length = length_t(0.1),
222 depth_t num_depth_levels = std::min(depth_t(17), Base::maxNumDepthLevels()))
223 : TreeSet(std::begin(range), std::end(range), leaf_node_length, num_depth_levels)
233 [[nodiscard]] iterator begin() { return iterator(this, Base::index()); }
235 [[nodiscard]] const_iterator begin() const
237 return const_iterator(const_cast<TreeSet*>(this), Base::index());
240 [[nodiscard]] const_iterator cbegin() const { return begin(); }
242 [[nodiscard]] iterator end() { return iterator(); }
244 [[nodiscard]] const_iterator end() const { return const_iterator(); }
246 [[nodiscard]] const_iterator cend() const { return end(); }
254 template <class Predicate>
255 [[nodiscard]] query_iterator_pred<Predicate> beginQuery(Predicate const& pred)
257 return query_iterator_pred<Predicate>(this, Base::index(), pred);
260 template <class Predicate>
261 [[nodiscard]] const_query_iterator_pred<Predicate> beginQuery(
262 Predicate const& pred) const
264 return const_query_iterator_pred<Predicate>(const_cast<TreeSet*>(this), Base::index(),
268 template <class Predicate>
269 [[nodiscard]] const_query_iterator_pred<Predicate> cbeginQuery(
270 Predicate const& pred) const
272 return beginQuery(pred);
275 [[nodiscard]] query_iterator endQuery() { return query_iterator(); }
277 [[nodiscard]] const_query_iterator endQuery() const { return const_query_iterator(); }
279 [[nodiscard]] const_query_iterator cendQuery() const { return endQuery(); }
287 template <class Geometry>
288 [[nodiscard]] nearest_iterator_geom<Geometry> beginNearest(Geometry const& query,
289 float epsilon = 0.0f)
291 return nearest_iterator_geom<Geometry>(this, Base::index(), query, epsilon);
294 template <class Geometry>
295 [[nodiscard]] const_nearest_iterator_geom<Geometry> beginNearest(
296 Geometry const& query, float epsilon = 0.0f) const
298 return const_nearest_iterator_geom<Geometry>(const_cast<TreeSet*>(this),
299 Base::index(), query, epsilon);
302 template <class Geometry>
303 [[nodiscard]] const_nearest_iterator_geom<Geometry> cbeginNearest(
304 Geometry const& query, float epsilon = 0.0f) const
306 return beginNearest(query, epsilon);
309 [[nodiscard]] nearest_iterator endNearest() { return nearest_iterator(); }
311 [[nodiscard]] const_nearest_iterator endNearest() const
313 return const_nearest_iterator();
316 [[nodiscard]] const_nearest_iterator cendNearest() const { return endNearest(); }
324 template <class Predicate, class Geometry>
325 [[nodiscard]] query_nearest_iterator_pred_geom<Predicate, Geometry> beginQueryNearest(
326 Predicate const& pred, Geometry const& query, float epsilon = 0.0f)
328 return query_nearest_iterator_pred_geom<Predicate, Geometry>(this, Base::index(),
329 pred, query, epsilon);
332 template <class Predicate, class Geometry>
333 [[nodiscard]] const_query_nearest_iterator_pred_geom<Predicate, Geometry>
334 beginQueryNearest(Predicate const& pred, Geometry const& query,
335 float epsilon = 0.0f) const
337 return const_query_nearest_iterator_pred_geom<Predicate, Geometry>(
338 const_cast<TreeSet*>(this), Base::index(), pred, query, epsilon);
341 template <class Predicate, class Geometry>
342 [[nodiscard]] const_query_nearest_iterator_pred_geom<Predicate, Geometry>
343 cbeginQueryNearest(Predicate const& pred, Geometry const& query,
344 float epsilon = 0.0f) const
346 return beginQueryNearest(pred, query, epsilon);
349 [[nodiscard]] query_nearest_iterator endQueryNearest()
351 return query_nearest_iterator();
354 [[nodiscard]] const_query_nearest_iterator endQueryNearest() const
356 return const_query_nearest_iterator();
359 [[nodiscard]] const_query_nearest_iterator cendQueryNearest() const
361 return endQueryNearest();
375 [[nodiscard]] bool empty() const noexcept { return 0 == size(); }
382 [[nodiscard]] size_type size() const noexcept { return size_; }
390 [[nodiscard]] Bounds bounds() const { return bounds(Base::index()); }
408 void insert(value_type const& value)
410 Index node = Base::create(value);
414 void insert(value_type&& value)
416 Index node = Base::create(value);
417 insert(node, std::move(value));
420 template <class InputIt>
421 void insert(InputIt first, InputIt last)
424 insert(execution::seq, first, last);
428 class ExecutionPolicy, class RandomIt,
429 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>, bool> = true>
430 void insert(ExecutionPolicy&& policy, RandomIt first, RandomIt last)
434 auto nodes = Base::create(std::forward<ExecutionPolicy>(policy), first, last);
436 for (std::size_t i{}; first != last; ++i, ++first) {
437 insert(nodes[i], *first);
441 void insert(std::initializer_list<value_type> ilist)
443 insert(ilist.begin(), ilist.end());
447 class ExecutionPolicy,
448 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>, bool> = true>
449 void insert(ExecutionPolicy&& policy, std::initializer_list<value_type> ilist)
451 insert(std::forward<ExecutionPolicy>(policy), ilist.begin(), ilist.end());
454 template <class Range>
455 void insert(Range const& r)
459 insert(begin(r), end(r));
463 class ExecutionPolicy, class Range,
464 std::enable_if_t<execution::is_execution_policy_v<ExecutionPolicy>, bool> = true>
465 void insert(ExecutionPolicy&& policy, Range const& r)
469 insert(std::forward<ExecutionPolicy>(policy), begin(r), end(r));
472 size_type erase(value_type const& value)
474 auto node = Base::index(value);
476 if (!Base::isPureLeaf(node)) {
480 auto& v = values(node);
481 size_type num_removed = v.size();
482 v.remove_if([&value](auto const& x) { return x == value; });
483 num_removed -= v.size();
485 size_ -= num_removed;
487 erasePropagate(node);
500 iterator erase(const_iterator pos)
502 auto it = pos.iterator();
505 return iterator(pos);
517 template <class Predicate>
518 query_iterator_pred<Predicate> erase(const_query_iterator_pred<Predicate> pos)
520 auto it = pos.iterator();
523 return query_iterator_pred<Predicate>(pos);
534 template <class Geometry>
535 nearest_iterator_geom<Geometry> erase(const_nearest_iterator_geom<Geometry> pos)
537 auto it = pos.iterator();
540 return nearest_iterator_geom<Geometry>(pos);
553 template <class Predicate, class Geometry>
554 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
555 const_query_nearest_iterator_pred_geom<Predicate, Geometry> pos)
557 auto it = pos.iterator();
560 return query_nearest_iterator_pred_geom<Predicate, Geometry>(pos);
573 iterator erase(const_iterator first, const_iterator last)
575 while (last != first) {
576 auto it = first.iterator();
580 return iterator(first);
595 template <class Predicate1, class Predicate2>
596 query_iterator_pred<Predicate1> erase(const_query_iterator_pred<Predicate1> first,
597 const_query_iterator_pred<Predicate2> last)
599 while (last != first) {
600 auto it = first.iterator();
604 return query_iterator_pred<Predicate1>(first);
613 template <class Predicate>
614 query_iterator_pred<Predicate> erase(ConstQuery<Predicate> query)
616 return erase(query.begin(), query.end());
629 template <class Geometry1, class Geometry2>
630 nearest_iterator_geom<Geometry1> erase(const_nearest_iterator_geom<Geometry1> first,
631 const_nearest_iterator_geom<Geometry2> last)
633 while (last != first) {
634 auto it = first.iterator();
638 return nearest_iterator_geom<Geometry1>(first);
654 template <class Predicate1, class Geometry1, class Predicate2, class Geometry2>
655 query_nearest_iterator_pred_geom<Predicate1, Geometry1> erase(
656 const_query_nearest_iterator_pred_geom<Predicate1, Geometry1> first,
657 const_query_nearest_iterator_pred_geom<Predicate2, Geometry2> last)
659 while (last != first) {
660 auto it = first.iterator();
664 return query_nearest_iterator_pred_geom<Predicate1, Geometry1>(first);
673 template <class Predicate, class Geometry>
674 query_nearest_iterator_pred_geom<Predicate, Geometry> erase(
675 ConstQueryNearest<Predicate, Geometry> query)
677 return erase(query.begin(), query.end());
685 void swap(TreeSet& other)
687 std::swap(size_, other.size_);
688 std::swap(static_cast<Base&>(*this), static_cast<Base&>(other));
704 [[nodiscard]] size_type count(Point point) const
706 auto const& v = values(Base::index(point));
707 return std::count_if(v.begin(), v.end(),
708 [point](auto const& x) { return x == point; });
718 [[nodiscard]] bool contains(Point point) const
720 auto const& v = values(Base::index(point));
721 return std::end(v) != std::find_if(v.begin(), v.end(),
722 [point](auto const& x) { return x == point; });
725 template <class Predicate>
726 [[nodiscard]] Query<Predicate> query(Predicate const& pred)
728 return Query<Predicate>(beginQuery(pred), endQuery());
731 template <class Predicate>
732 [[nodiscard]] ConstQuery<Predicate> query(Predicate const& pred) const
734 return ConstQuery<Predicate>(beginQuery(pred), endQuery());
737 template <class Geometry>
738 [[nodiscard]] Nearest<Geometry> nearest(Geometry const& query, float epsilon = 0.0f)
740 return Nearest<Geometry>(beginNearest(query, epsilon), endNearest());
743 template <class Geometry>
744 [[nodiscard]] ConstNearest<Geometry> nearest(Geometry const& query,
745 float epsilon = 0.0f) const
747 return ConstNearest<Geometry>(beginNearest(query, epsilon), endNearest());
750 template <class Predicate, class Geometry>
751 [[nodiscard]] QueryNearest<Predicate, Geometry> queryNearest(Predicate const& pred,
752 Geometry const& query,
753 float epsilon = 0.0f)
755 return QueryNearest<Predicate, Geometry>(beginQueryNearest(pred, query, epsilon),
759 template <class Predicate, class Geometry>
760 [[nodiscard]] ConstQueryNearest<Predicate, Geometry> queryNearest(
761 Predicate const& pred, Geometry const& query, float epsilon = 0.0f) const
763 return ConstQueryNearest<Predicate, Geometry>(beginQueryNearest(pred, query, epsilon),
767 template <class Geometry>
768 [[nodiscard]] float nearestDistance(
769 Geometry const& query, float max_distance = std::numeric_limits<float>::infinity(),
770 float epsilon = 0.0f,
771 NearestSearchAlgorithm search_alg = NearestSearchAlgorithm::DEPTH_FIRST) const
773 float max_distance_sq = max_distance * max_distance;
776 Base::index(), search_alg,
777 [this, &query](Index node) {
778 float dist_sq = std::numeric_limits<float>::infinity();
779 for (auto e : values(node)) {
780 dist_sq = UFO_MIN(dist_sq, distanceSquared(query, e));
784 [this, &query](Index node) { return distanceSquared(query, bounds(node)); },
785 max_distance_sq, epsilon * epsilon)
788 return max_distance_sq <= dist_sq ? max_distance : std::sqrt(dist_sq);
791 template <class Geometry>
792 [[nodiscard]] std::pair<value_type, float> nearestPoint(
793 Geometry const& query, float max_distance = std::numeric_limits<float>::infinity(),
794 float epsilon = 0.0f,
795 NearestSearchAlgorithm search_alg = NearestSearchAlgorithm::DEPTH_FIRST) const
797 float max_distance_sq = max_distance * max_distance;
798 auto [dist_sq, node] = Base::nearest(
799 Base::index(), search_alg,
800 [this, &query](Index node) {
801 float dist_sq = std::numeric_limits<float>::infinity();
802 for (auto e : values(node)) {
803 dist_sq = UFO_MIN(dist_sq, distanceSquared(query, e));
807 [this, &query](Index node) { return distanceSquared(query, bounds(node)); },
808 max_distance_sq, epsilon * epsilon);
810 value_type value(std::numeric_limits<typename value_type::value_type>::quiet_NaN());
812 for (auto const& e : values(node)) {
813 value = distanceSquared(query, e) == dist_sq ? e : value;
816 return {value, max_distance_sq <= dist_sq ? max_distance : std::sqrt(dist_sq)};
832 template <class NodeType,
833 std::enable_if_t<Base::template is_node_type_v<NodeType>, bool> = true>
834 [[nodiscard]] Bounds& bounds(NodeType node)
836 TreeIndex n = Base::index(node);
837 return Base::treeBlock(n).bounds[n.offset];
847 template <class NodeType,
848 std::enable_if_t<Base::template is_node_type_v<NodeType>, bool> = true>
849 [[nodiscard]] Bounds const& bounds(NodeType node) const
851 TreeIndex n = Base::index(node);
852 return Base::treeBlock(n).bounds[n.offset];
861 template <std::size_t D>
862 friend bool operator==(TreeSet<D> const& lhs, TreeSet<D> const& rhs);
864 template <std::size_t D>
865 friend bool operator!=(TreeSet<D> const& lhs, TreeSet<D> const& rhs);
876 void onInitChildren(Index , pos_t ) {}
878 void onPruneChildren(Index , pos_t ) {}
892 [[nodiscard]] bool empty(Index node) const noexcept
894 return boundsMin(node)[0] > boundsMax(node)[0];
903 void insert(Index node, value_type const& value)
905 values(node).push_back(value);
908 insertPropagate(node, value);
911 void insert(Index node, value_type&& value)
913 values(node).push_back(std::move(value));
916 insertPropagate(node, value);
919 void insertPropagate(Index node, Point p)
922 auto root_depth = Base::depth();
923 auto depth = Base::depth(node);
924 for (; root_depth > depth; ++depth) {
925 Point& min = boundsMin(node);
926 Point& max = boundsMax(node);
927 min = ufo::min(min, p);
928 max = ufo::max(max, p);
929 node = Base::parent(node);
933 Point& min = boundsMin(node);
934 Point& max = boundsMax(node);
935 min = ufo::min(min, p);
936 max = ufo::max(max, p);
939 void erase(typename container_type::const_iterator it)
941 auto node = Base::index(*it);
943 if (!Base::isPureLeaf(node)) {
947 auto& v = values(node);
951 erasePropagate(node);
954 void erasePropagate(Index node)
956 Point min(std::numeric_limits<typename Point::value_type>::max());
957 Point max(std::numeric_limits<typename Point::value_type>::lowest());
958 for (auto const& p : values(node)) {
959 min = ufo::min(min, p);
960 max = ufo::max(max, p);
962 boundsMin(node) = min;
963 boundsMax(node) = max;
965 if (Base::isRoot(node)) {
969 auto root_depth = Base::depth();
970 auto child_block = node.pos;
971 node = Base::parent(node);
972 auto depth = Base::depth(node);
973 for (; root_depth > depth; ++depth) {
974 Point min = boundsMin(Index(child_block, 0));
975 Point max = boundsMax(Index(child_block, 0));
976 for (std::size_t i = 1; Base::BF > i; ++i) {
977 min = ufo::min(min, boundsMin(Index(child_block, i)));
978 max = ufo::max(max, boundsMax(Index(child_block, i)));
980 boundsMin(node) = min;
981 boundsMax(node) = max;
982 child_block = node.pos;
983 node = Base::parent(node);
987 min = boundsMin(Index(child_block, 0));
988 max = boundsMax(Index(child_block, 0));
989 for (std::size_t i = 1; Base::BF > i; ++i) {
990 min = ufo::min(min, boundsMin(Index(child_block, i)));
991 max = ufo::max(max, boundsMax(Index(child_block, i)));
993 boundsMin(node) = min;
994 boundsMax(node) = max;
1003 [[nodiscard]] auto& values(pos_t block) { return Base::treeBlock(block).values; }
1005 [[nodiscard]] auto const& values(pos_t block) const
1007 return Base::treeBlock(block).values;
1010 [[nodiscard]] auto& values(Index node)
1012 return Base::treeBlock(node).values[node.offset];
1015 [[nodiscard]] auto const& values(Index node) const
1017 return Base::treeBlock(node).values[node.offset];
1028 [[nodiscard]] Point& boundsMin(Index node)
1030 return Base::treeBlock(node).bounds[node.offset].min;
1041 [[nodiscard]] Point boundsMin(Index node) const
1043 return Base::treeBlock(node).bounds[node.offset].min;
1054 [[nodiscard]] Point& boundsMax(Index node)
1056 return Base::treeBlock(node).bounds[node.offset].max;
1067 [[nodiscard]] Point boundsMax(Index node) const
1069 return Base::treeBlock(node).bounds[node.offset].max;