OpenMS
Loading...
Searching...
No Matches
KDTree.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Johannes Veit $
6// $Authors: Johannes Veit $
7// --------------------------------------------------------------------------
8
9/* Note: This file contains a concatenation of the 6 header files comprising
10 * libkdtree++ (node.hpp, function.hpp, allocator.hpp, iterator.hpp,
11 * region.hpp, kdtree.hpp).
12 *
13 * Johannes Veit (2016)
14 */
15
16/* COPYRIGHT --
17 *
18 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
19 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
20 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
21 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
22 * root for more information.
23 *
24 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 */
28
35#ifndef OPENMS_DATASTRUCTURES_KDTREE_H
36#define OPENMS_DATASTRUCTURES_KDTREE_H
37
38#ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
39# include <ostream>
40#endif
41
42#include <cstddef>
43#include <cmath>
44#include <memory>
45
46namespace KDTree
47{
49{
52
56
57 _Node_base(_Base_ptr const __PARENT = nullptr,
58 _Base_ptr const __LEFT = nullptr,
59 _Base_ptr const __RIGHT = nullptr)
60 : _M_parent(__PARENT), _M_left(__LEFT), _M_right(__RIGHT) {}
61
62 static _Base_ptr
64 {
65 while (__x->_M_left) __x = __x->_M_left;
66 return __x;
67 }
68
69 static _Base_ptr
71 {
72 while (__x->_M_right) __x = __x->_M_right;
73 return __x;
74 }
75};
76
77template <typename _Val>
78struct _Node : public _Node_base
79{
81 typedef _Node* _Link_type;
82
84
85 _Node(_Val const& __VALUE = _Val(),
86 _Base_ptr const __PARENT = nullptr,
87 _Base_ptr const __LEFT = nullptr,
88 _Base_ptr const __RIGHT = nullptr)
89 : _Node_base(__PARENT, __LEFT, __RIGHT), _M_value(__VALUE) {}
90
91#ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
92
93 template <typename Char, typename Traits>
94 friend
95 std::basic_ostream<Char, Traits>&
96 operator<<(typename std::basic_ostream<Char, Traits>& out,
97 _Node_base const& node)
98 {
99 out << &node;
100 out << " parent: " << node._M_parent;
101 out << "; left: " << node._M_left;
102 out << "; right: " << node._M_right;
103 return out;
104 }
105
106 template <typename Char, typename Traits>
107 friend
108 std::basic_ostream<Char, Traits>&
109 operator<<(typename std::basic_ostream<Char, Traits>& out,
110 _Node<_Val> const& node)
111 {
112 out << &node;
113 out << ' ' << node._M_value;
114 out << "; parent: " << node._M_parent;
115 out << "; left: " << node._M_left;
116 out << "; right: " << node._M_right;
117 return out;
118 }
119
120#endif
121};
122
123template <typename _Val, typename _Acc, typename _Cmp>
125{
126public:
127 _Node_compare(size_t const __DIM, _Acc const& acc, _Cmp const& cmp)
128 : _M_DIM(__DIM), _M_acc(acc), _M_cmp(cmp) {}
129
130 bool
131 operator()(_Val const& __A, _Val const& __B) const
132 {
133 return _M_cmp(_M_acc(__A, _M_DIM), _M_acc(__B, _M_DIM));
134 }
135
136private:
137 size_t _M_DIM; // don't make this const so that an assignment operator can be auto-generated
138 _Acc _M_acc;
139 _Cmp _M_cmp;
140};
141
148template <typename _ValA, typename _ValB, typename _Cmp,
149 typename _Acc>
150inline
151bool
152_S_node_compare (const size_t __dim,
153 const _Cmp& __cmp, const _Acc& __acc,
154 const _ValA& __a, const _ValB& __b)
155{
156 return __cmp(__acc(__a, __dim), __acc(__b, __dim));
157}
158
164template <typename _ValA, typename _ValB, typename _Dist,
165 typename _Acc>
166inline
167typename _Dist::distance_type
168_S_node_distance (const size_t __dim,
169 const _Dist& __dist, const _Acc& __acc,
170 const _ValA& __a, const _ValB& __b)
171{
172 return __dist(__acc(__a, __dim), __acc(__b, __dim));
173}
174
181template <typename _ValA, typename _ValB, typename _Dist,
182 typename _Acc>
183inline
184typename _Dist::distance_type
185_S_accumulate_node_distance (const size_t __dim,
186 const _Dist& __dist, const _Acc& __acc,
187 const _ValA& __a, const _ValB& __b)
188{
189 typename _Dist::distance_type d = 0;
190 for (size_t i=0; i<__dim; ++i)
191 d += __dist(__acc(__a, i), __acc(__b, i));
192 return d;
193}
194
200template <typename _Val, typename _Cmp, typename _Acc, typename NodeType>
201inline
202const NodeType*
203_S_node_descend (const size_t __dim,
204 const _Cmp& __cmp, const _Acc& __acc,
205 const _Val& __val, const NodeType* __node)
206{
207 if (_S_node_compare(__dim, __cmp, __acc, __val, __node->_M_value))
208 return static_cast<const NodeType *>(__node->_M_left);
209 return static_cast<const NodeType *>(__node->_M_right);
210}
211
220template <class SearchVal,
221 typename NodeType, typename _Cmp,
222 typename _Acc, typename _Dist,
223 typename _Predicate>
224inline
225std::pair<const NodeType*,
226std::pair<size_t, typename _Dist::distance_type> >
227_S_node_nearest (const size_t __k, size_t __dim, SearchVal const& __val,
228 const NodeType* __node, const _Node_base* __end,
229 const NodeType* __best, typename _Dist::distance_type __max,
230 const _Cmp& __cmp, const _Acc& __acc, const _Dist& __dist,
231 _Predicate __p)
232{
233 typedef const NodeType* NodePtr;
234 NodePtr pcur = __node;
235 NodePtr cur = _S_node_descend(__dim % __k, __cmp, __acc, __val, __node);
236 size_t cur_dim = __dim+1;
237 // find the smallest __max distance in direct descent
238 while (cur)
239 {
240 if (__p(cur->_M_value))
241 {
242 typename _Dist::distance_type d = 0;
243 for (size_t i=0; i != __k; ++i)
244 d += _S_node_distance(i, __dist, __acc, __val, cur->_M_value);
245 d = std::sqrt(d);
246 if (d <= __max)
247 // ("bad candidate notes")
248 // Changed: removed this test: || ( d == __max && cur < __best ))
249 // Can't do this optimisation without checking that the current 'best' is not the root AND is not a valid candidate...
250 // This is because find_nearest() etc will call this function with the best set to _M_root EVEN IF _M_root is not a valid answer (eg too far away or doesn't pass the predicate test)
251 {
252 __best = cur;
253 __max = d;
254 __dim = cur_dim;
255 }
256 }
257 pcur = cur;
258 cur = _S_node_descend(cur_dim % __k, __cmp, __acc, __val, cur);
259 ++cur_dim;
260 }
261 // Swap cur to prev, only prev is a valid node.
262 cur = pcur;
263 --cur_dim;
264 pcur = NULL;
265 // Probe all node's children not visited yet (siblings of the visited nodes).
266 NodePtr probe = cur;
267 NodePtr pprobe = probe;
268 NodePtr near_node;
269 NodePtr far_node;
270 size_t probe_dim = cur_dim;
271 if (_S_node_compare(probe_dim % __k, __cmp, __acc, __val, probe->_M_value))
272 near_node = static_cast<NodePtr>(probe->_M_right);
273 else
274 near_node = static_cast<NodePtr>(probe->_M_left);
275 if (near_node
276 // only visit node's children if node's plane intersect hypersphere
277 && (std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max))
278 {
279 probe = near_node;
280 ++probe_dim;
281 }
282 while (cur != __end)
283 {
284 while (probe != cur)
285 {
286 if (_S_node_compare(probe_dim % __k, __cmp, __acc, __val, probe->_M_value))
287 {
288 near_node = static_cast<NodePtr>(probe->_M_left);
289 far_node = static_cast<NodePtr>(probe->_M_right);
290 }
291 else
292 {
293 near_node = static_cast<NodePtr>(probe->_M_right);
294 far_node = static_cast<NodePtr>(probe->_M_left);
295 }
296 if (pprobe == probe->_M_parent) // going downward ...
297 {
298 if (__p(probe->_M_value))
299 {
300 typename _Dist::distance_type d = 0;
301 for (size_t i=0; i < __k; ++i)
302 d += _S_node_distance(i, __dist, __acc, __val, probe->_M_value);
303 d = std::sqrt(d);
304 if (d <= __max) // CHANGED, see the above notes ("bad candidate notes")
305 {
306 __best = probe;
307 __max = d;
308 __dim = probe_dim;
309 }
310 }
311 pprobe = probe;
312 if (near_node)
313 {
314 probe = near_node;
315 ++probe_dim;
316 }
317 else if (far_node &&
318 // only visit node's children if node's plane intersect hypersphere
319 std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max)
320 {
321 probe = far_node;
322 ++probe_dim;
323 }
324 else
325 {
326 probe = static_cast<NodePtr>(probe->_M_parent);
327 --probe_dim;
328 }
329 }
330 else // ... and going upward.
331 {
332 if (pprobe == near_node && far_node
333 // only visit node's children if node's plane intersect hypersphere
334 && std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max)
335 {
336 pprobe = probe;
337 probe = far_node;
338 ++probe_dim;
339 }
340 else
341 {
342 pprobe = probe;
343 probe = static_cast<NodePtr>(probe->_M_parent);
344 --probe_dim;
345 }
346 }
347 }
348 pcur = cur;
349 cur = static_cast<NodePtr>(cur->_M_parent);
350 --cur_dim;
351 pprobe = cur;
352 probe = cur;
353 probe_dim = cur_dim;
354 if (cur != __end)
355 {
356 if (pcur == cur->_M_left)
357 near_node = static_cast<NodePtr>(cur->_M_right);
358 else
359 near_node = static_cast<NodePtr>(cur->_M_left);
360 if (near_node
361 // only visit node's children if node's plane intersect hypersphere
362 && (std::sqrt(_S_node_distance(cur_dim % __k, __dist, __acc, __val, cur->_M_value)) <= __max))
363 {
364 probe = near_node;
365 ++probe_dim;
366 }
367 }
368 }
369 return std::pair<NodePtr,
370 std::pair<size_t, typename _Dist::distance_type> >
371 (__best, std::pair<size_t, typename _Dist::distance_type>
372 (__dim, __max));
373}
374
375
376} // namespace KDTree
377
378#endif // include guard
379
380/* COPYRIGHT --
381 *
382 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
383 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
384 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
385 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
386 * root for more information.
387 *
388 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
389 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
390 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
391 */
399#ifndef INCLUDE_KDTREE_ACCESSOR_HPP
400#define INCLUDE_KDTREE_ACCESSOR_HPP
401
402#include <cstddef>
403
404namespace KDTree
405{
406template <typename _Val>
408{
409 typedef typename _Val::value_type result_type;
410
412 operator()(_Val const& V, size_t const N) const
413 {
414 return V[N];
415 }
416};
417
418template <typename _Tp>
420{
421 bool operator() (const _Tp& ) const { return true; }
422};
423
424template <typename _Tp, typename _Dist>
426{
427 typedef _Dist distance_type;
428
430 operator() (const _Tp& __a, const _Tp& __b) const
431 {
432 distance_type d=__a - __b;
433 return d*d;
434 }
435};
436
437template <typename _Tp, typename _Dist>
439{
440 typedef _Dist distance_type;
441
445
446 void reset ()
447 { _M_count = 0; }
448
449 long&
450 count () const
451 { return _M_count; }
452
454 operator() (const _Tp& __a, const _Tp& __b) const
455 {
456 distance_type d=__a - __b;
457 ++_M_count;
458 return d*d;
459 }
460
461private:
462 mutable long _M_count;
463};
464
465} // namespace KDTree
466
467#endif // include guard
468
469/* COPYRIGHT --
470 *
471 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
472 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
473 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
474 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
475 * root for more information.
476 *
477 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
478 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
479 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
480 */
487#ifndef INCLUDE_KDTREE_ALLOCATOR_HPP
488#define INCLUDE_KDTREE_ALLOCATOR_HPP
489
490#include <cstddef>
491
492namespace KDTree
493{
494
495template <typename _Tp, typename _Alloc>
497{
498public:
500 typedef typename _Node_::_Base_ptr _Base_ptr;
501 typedef _Alloc allocator_type;
502
505
508 {
509 return _M_node_allocator;
510 }
511
512
514 {
517
518 public:
520
521 _Node_ * get() { return new_node; }
522 void disconnect() { new_node = nullptr; }
523
525 };
526
527
528protected:
530
531 _Node_*
533 {
534 return _M_node_allocator.allocate(1);
535 }
536
537 void
539 {
540 return _M_node_allocator.deallocate(__P, 1);
541 }
542
543 void
544 _M_construct_node(_Node_* __p, _Tp const __V = _Tp(),
545 _Base_ptr const __PARENT = NULL,
546 _Base_ptr const __LEFT = NULL,
547 _Base_ptr const __RIGHT = NULL)
548 {
549 new (__p) _Node_(__V, __PARENT, __LEFT, __RIGHT);
550 }
551
552 void
554 {
555 std::allocator_traits<allocator_type>::destroy(_M_node_allocator, __p);
556 }
557};
558
559} // namespace KDTree
560
561#endif // include guard
562
563/* COPYRIGHT --
564 *
565 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
566 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
567 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
568 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
569 * root for more information.
570 *
571 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
572 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
573 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
574 */
581#ifndef INCLUDE_KDTREE_ITERATOR_HPP
582#define INCLUDE_KDTREE_ITERATOR_HPP
583
584#include <iterator>
585
586namespace KDTree
587{
588template <typename _Val, typename _Ref, typename _Ptr>
589class _Iterator;
590
591template<typename _Val, typename _Ref, typename _Ptr>
592inline bool
593operator==(_Iterator<_Val, _Ref, _Ptr> const&,
594 _Iterator<_Val, _Ref, _Ptr> const&);
595
596template<typename _Val>
597inline bool
598operator==(_Iterator<_Val, const _Val&, const _Val*> const&,
599 _Iterator<_Val, _Val&, _Val*> const&);
600
601template<typename _Val>
602inline bool
603operator==(_Iterator<_Val, _Val&, _Val*> const&,
604 _Iterator<_Val, const _Val&, const _Val*> const&);
605
606template<typename _Val, typename _Ref, typename _Ptr>
607inline bool
608operator!=(_Iterator<_Val, _Ref, _Ptr> const&,
609 _Iterator<_Val, _Ref, _Ptr> const&);
610
611template<typename _Val>
612inline bool
613operator!=(_Iterator<_Val, const _Val&, const _Val*> const&,
614 _Iterator<_Val, _Val&, _Val*> const&);
615
616template<typename _Val>
617inline bool
618operator!=(_Iterator<_Val, _Val&, _Val*> const&,
619 _Iterator<_Val, const _Val&, const _Val*> const&);
620
622{
623protected:
626
627 inline _Base_iterator(_Base_const_ptr const __N = nullptr)
628 : _M_node(__N) {}
629 inline _Base_iterator(_Base_iterator const& __THAT)
630 : _M_node(__THAT._M_node) {}
631
632 inline void
634 {
635 if (_M_node->_M_right)
636 {
637 _M_node = _M_node->_M_right;
638 while (_M_node->_M_left) _M_node = _M_node->_M_left;
639 }
640 else
641 {
642 _Base_const_ptr __p = _M_node->_M_parent;
643 while (__p && _M_node == __p->_M_right)
644 {
645 _M_node = __p;
646 __p = _M_node->_M_parent;
647 }
648 if (__p) // (__p) provide undetermined behavior on end()++ rather
649 // than a segfault, similar to standard iterator.
650 _M_node = __p;
651 }
652 }
653
654 inline void
656 {
657 if (!_M_node->_M_parent) // clearly identify the header node
658 {
659 _M_node = _M_node->_M_right;
660 }
661 else if (_M_node->_M_left)
662 {
663 _Base_const_ptr x = _M_node->_M_left;
664 while (x->_M_right) x = x->_M_right;
665 _M_node = x;
666 }
667 else
668 {
669 _Base_const_ptr __p = _M_node->_M_parent;
670 while (__p && _M_node == __p->_M_left) // see below
671 {
672 _M_node = __p;
673 __p = _M_node->_M_parent;
674 }
675 if (__p) // (__p) provide undetermined behavior on rend()++ rather
676 // than a segfault, similar to standard iterator.
677 _M_node = __p;
678 }
679 }
680
681 template <size_t const __K, typename _Val, typename _Acc,
682 typename _Dist, typename _Cmp, typename _Alloc>
683 friend class KDTree;
684};
685
686template <typename _Val, typename _Ref, typename _Ptr>
687class _Iterator : protected _Base_iterator
688{
689public:
690 typedef _Val value_type;
691 typedef _Ref reference;
692 typedef _Ptr pointer;
697 typedef std::bidirectional_iterator_tag iterator_category;
698 typedef ptrdiff_t difference_type;
699
700 inline _Iterator()
701 : _Base_iterator() {}
702 inline _Iterator(_Link_const_type const __N)
703 : _Base_iterator(__N) {}
704 inline _Iterator(iterator const& __THAT)
705 : _Base_iterator(__THAT) {}
706
708 {
710 }
711
713 operator*() const
714 {
715 return _Link_const_type(_M_node)->_M_value;
716 }
717
718 pointer
720 {
721 return &(operator*());
722 }
723
724 _Self
726 {
727 _M_increment();
728 return *this;
729 }
730
731 _Self
733 {
734 _Self ret = *this;
735 _M_increment();
736 return ret;
737 }
738
739 _Self&
741 {
742 _M_decrement();
743 return *this;
744 }
745
746 _Self
748 {
749 _Self ret = *this;
750 _M_decrement();
751 return ret;
752 }
753
754 friend bool
755 operator== <>(_Iterator<_Val, _Ref, _Ptr> const&,
757
758 friend bool
761
762 friend bool
763 operator== <>(_Iterator<_Val, _Val&, _Val*> const&,
765
766 friend bool
767 operator!= <>(_Iterator<_Val, _Ref, _Ptr> const&,
769
770 friend bool
773
774 friend bool
775 operator!= <>(_Iterator<_Val, _Val&, _Val*> const&,
777};
778
779template<typename _Val, typename _Ref, typename _Ptr>
780bool
783{ return __X._M_node == __Y._M_node; }
784
785template<typename _Val>
786bool
790
791template<typename _Val>
792bool
796
797template<typename _Val, typename _Ref, typename _Ptr>
798bool
801{ return __X._M_node != __Y._M_node; }
802
803template<typename _Val>
804bool
808
809template<typename _Val>
810bool
814
815} // namespace KDTree
816
817#endif // include guard
818
819/* COPYRIGHT --
820 *
821 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
822 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
823 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
824 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
825 * root for more information.
826 *
827 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
828 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
829 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
830 */
837#ifndef INCLUDE_KDTREE_REGION_HPP
838#define INCLUDE_KDTREE_REGION_HPP
839
840#include <cstddef>
841
842namespace KDTree
843{
844
845template <size_t const __K, typename _Val, typename _SubVal,
846 typename _Acc, typename _Cmp>
848{
849 typedef _Val value_type;
850 typedef _SubVal subvalue_type;
851
852 // special typedef for checking against a fuzzy point (for find_nearest)
853 // Note the region (first) component is not supposed to have an area, its
854 // bounds should all be set to a specific point.
855 typedef std::pair<_Region,_SubVal> _CenterPt;
856
857 _Region(_Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
858 : _M_acc(__acc), _M_cmp(__cmp) {}
859
860 template <typename Val>
861 _Region(Val const& __V,
862 _Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
863 : _M_acc(__acc), _M_cmp(__cmp)
864 {
865 for (size_t __i = 0; __i != __K; ++__i)
866 {
867 _M_low_bounds[__i] = _M_high_bounds[__i] = _M_acc(__V,__i);
868 }
869 }
870
871 template <typename Val>
872 _Region(Val const& __V, subvalue_type const& __R,
873 _Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
874 : _M_acc(__acc), _M_cmp(__cmp)
875 {
876 for (size_t __i = 0; __i != __K; ++__i)
877 {
878 _M_low_bounds[__i] = _M_acc(__V,__i) - __R;
879 _M_high_bounds[__i] = _M_acc(__V,__i) + __R;
880 }
881 }
882
883 bool
884 intersects_with(_CenterPt const& __THAT) const
885 {
886 for (size_t __i = 0; __i != __K; ++__i)
887 {
888 // does it fall outside the bounds?
889 // ! low-tolerance <= x <= high+tolerance
890 // ! (low-tol <= x and x <= high+tol)
891 // !low-tol<=x or !x<=high+tol
892 // low-tol>x or x>high+tol
893 // x<low-tol or high+tol<x
894 if (_M_cmp(__THAT.first._M_low_bounds[__i], _M_low_bounds[__i] - __THAT.second)
895 || _M_cmp(_M_high_bounds[__i] + __THAT.second, __THAT.first._M_low_bounds[__i]))
896 return false;
897 }
898 return true;
899 }
900
901 bool
902 intersects_with(_Region const& __THAT) const
903 {
904 for (size_t __i = 0; __i != __K; ++__i)
905 {
906 if (_M_cmp(__THAT._M_high_bounds[__i], _M_low_bounds[__i])
907 || _M_cmp(_M_high_bounds[__i], __THAT._M_low_bounds[__i]))
908 return false;
909 }
910 return true;
911 }
912
913 bool
914 encloses(value_type const& __V) const
915 {
916 for (size_t __i = 0; __i != __K; ++__i)
917 {
918 if (_M_cmp(_M_acc(__V, __i), _M_low_bounds[__i])
919 || _M_cmp(_M_high_bounds[__i], _M_acc(__V, __i)))
920 return false;
921 }
922 return true;
923 }
924
925 _Region&
926 set_high_bound(value_type const& __V, size_t const __L)
927 {
928 _M_high_bounds[__L % __K] = _M_acc(__V, __L % __K);
929 return *this;
930 }
931
932 _Region&
933 set_low_bound(value_type const& __V, size_t const __L)
934 {
935 _M_low_bounds[__L % __K] = _M_acc(__V, __L % __K);
936 return *this;
937 }
938
940 _Acc _M_acc;
941 _Cmp _M_cmp;
942};
943
944} // namespace KDTree
945
946#endif // include guard
947
948/* COPYRIGHT --
949 *
950 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
951 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
952 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
953 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
954 * root for more information.
955 *
956 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
957 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
958 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
959 */
1005#ifndef INCLUDE_KDTREE_KDTREE_HPP
1006#define INCLUDE_KDTREE_KDTREE_HPP
1007
1008
1009//
1010// This number is guaranteed to change with every release.
1011//
1012// KDTREE_VERSION % 100 is the patch level
1013// KDTREE_VERSION / 100 % 1000 is the minor version
1014// KDTREE_VERSION / 100000 is the major version
1015#define KDTREE_VERSION 701
1016//
1017// KDTREE_LIB_VERSION must be defined to be the same as KDTREE_VERSION
1018// but as a *string* in the form "x_y[_z]" where x is the major version
1019// number, y is the minor version number, and z is the patch level if not 0.
1020#define KDTREE_LIB_VERSION "0_7_1"
1021
1022
1023#include <vector>
1024
1025#ifdef KDTREE_CHECK_PERFORMANCE_COUNTERS
1026# include <map>
1027#endif
1028#include <algorithm>
1029#include <functional>
1030
1031#ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
1032# include <ostream>
1033# include <stack>
1034#endif
1035
1036#include <cmath>
1037#include <cstddef>
1038#include <cassert>
1039
1040namespace KDTree
1041{
1042
1043#ifdef KDTREE_CHECK_PERFORMANCE
1044unsigned long long num_dist_calcs = 0;
1045#endif
1046
1047template <size_t const __K, typename _Val,
1048 typename _Acc = _Bracket_accessor<_Val>,
1049 typename _Dist = squared_difference<typename _Acc::result_type,
1050 typename _Acc::result_type>,
1051 typename _Cmp = std::less<typename _Acc::result_type>,
1052 typename _Alloc = std::allocator<_Node<_Val> > >
1053class KDTree : protected _Alloc_base<_Val, _Alloc>
1054{
1055protected:
1058
1063
1065
1066public:
1068 typedef _Val value_type;
1073 typedef typename _Acc::result_type subvalue_type;
1074 typedef typename _Dist::distance_type distance_type;
1075 typedef size_t size_type;
1076 typedef ptrdiff_t difference_type;
1077
1078 KDTree(_Acc const& __acc = _Acc(), _Dist const& __dist = _Dist(),
1079 _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
1080 : _Base(__a), _M_header(),
1081 _M_count(0), _M_acc(__acc), _M_cmp(__cmp), _M_dist(__dist)
1082 {
1083 _M_empty_initialise();
1084 }
1085
1086 KDTree(const KDTree& __x)
1087 : _Base(__x.get_allocator()), _M_header(), _M_count(0),
1088 _M_acc(__x._M_acc), _M_cmp(__x._M_cmp), _M_dist(__x._M_dist)
1089 {
1090 _M_empty_initialise();
1091 // this is slow:
1092 // this->insert(begin(), __x.begin(), __x.end());
1093 // this->optimise();
1094
1095 // this is much faster, as it skips a lot of useless work
1096 // do the optimisation before inserting
1097 // Needs to be stored in a vector first as _M_optimise()
1098 // sorts the data in the passed iterators directly.
1099 std::vector<value_type> temp;
1100 temp.reserve(__x.size());
1101 std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
1102 _M_optimise(temp.begin(), temp.end(), 0);
1103 }
1104
1105 template<typename _InputIterator>
1106 KDTree(_InputIterator __first, _InputIterator __last,
1107 _Acc const& acc = _Acc(), _Dist const& __dist = _Dist(),
1108 _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
1109 : _Base(__a), _M_header(), _M_count(0),
1110 _M_acc(acc), _M_cmp(__cmp), _M_dist(__dist)
1111 {
1112 _M_empty_initialise();
1113 // this is slow:
1114 // this->insert(begin(), __first, __last);
1115 // this->optimise();
1116
1117 // this is much faster, as it skips a lot of useless work
1118 // do the optimisation before inserting
1119 // Needs to be stored in a vector first as _M_optimise()
1120 // sorts the data in the passed iterators directly.
1121 std::vector<value_type> temp;
1122 temp.reserve(std::distance(__first,__last));
1123 std::copy(__first,__last,std::back_inserter(temp));
1124 _M_optimise(temp.begin(), temp.end(), 0);
1125
1126 // NOTE: this will BREAK users that are passing in
1127 // read-once data via the iterator...
1128 // We increment __first all the way to __last once within
1129 // the distance() call, and again within the copy() call.
1130 //
1131 // This should end up using some funky C++ concepts or
1132 // type traits to check that the iterators can be used in this way...
1133 }
1134
1135
1136 // this will CLEAR the tree and fill it with the contents
1137 // of 'writable_vector'. it will use the passed vector directly,
1138 // and will basically resort the vector many times over while
1139 // optimising the tree.
1140 //
1141 // Paul: I use this when I have already built up a vector of data
1142 // that I want to add, and I don't mind if its contents get shuffled
1143 // by the kdtree optimise routine.
1144 void efficient_replace_and_optimise( std::vector<value_type> & writable_vector )
1145 {
1146 this->clear();
1147 _M_optimise(writable_vector.begin(), writable_vector.end(), 0);
1148 }
1149
1150
1151
1152 KDTree&
1153 operator=(const KDTree& __x)
1154 {
1155 if (this != &__x)
1156 {
1157 _M_acc = __x._M_acc;
1158 _M_dist = __x._M_dist;
1159 _M_cmp = __x._M_cmp;
1160 // this is slow:
1161 // this->insert(begin(), __x.begin(), __x.end());
1162 // this->optimise();
1163
1164 // this is much faster, as it skips a lot of useless work
1165 // do the optimisation before inserting
1166 // Needs to be stored in a vector first as _M_optimise()
1167 // sorts the data in the passed iterators directly.
1168 std::vector<value_type> temp;
1169 temp.reserve(__x.size());
1170 std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
1171 efficient_replace_and_optimise(temp);
1172 }
1173 return *this;
1174 }
1175
1177 {
1178 this->clear();
1179 }
1180
1181 allocator_type
1183 {
1184 return _Base::get_allocator();
1185 }
1186
1187 size_type
1188 size() const
1189 {
1190 return _M_count;
1191 }
1192
1193 size_type
1194 max_size() const
1195 {
1196 return size_type(-1);
1197 }
1198
1199 bool
1200 empty() const
1201 {
1202 return this->size() == 0;
1203 }
1204
1205 void
1207 {
1208 _M_erase_subtree(_M_get_root());
1209 _M_set_leftmost(&_M_header);
1210 _M_set_rightmost(&_M_header);
1211 _M_set_root(nullptr);
1212 _M_count = 0;
1213 }
1214
1220 _Cmp
1222 { return _M_cmp; }
1223
1229 _Acc
1231 { return _M_acc; }
1232
1239 const _Dist&
1241 { return _M_dist; }
1242
1243 _Dist&
1245 { return _M_dist; }
1246
1247 // typedef _Iterator<_Val, reference, pointer> iterator;
1249 // No mutable iterator at this stage
1251 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1252 typedef std::reverse_iterator<iterator> reverse_iterator;
1253
1254 // Note: the static_cast in end() is invalid (_M_header is not convertible to a _Link_type), but
1255 // that's ok as it just means undefined behaviour if the user dereferences the end() iterator.
1256
1257 const_iterator begin() const { return const_iterator(_M_get_leftmost()); }
1258 const_iterator end() const { return const_iterator(static_cast<_Link_const_type>(&_M_header)); }
1261
1262 iterator
1263 insert(iterator /* ignored */, const_reference __V)
1264 {
1265 return this->insert(__V);
1266 }
1267
1268 iterator
1270 {
1271 if (!_M_get_root())
1272 {
1273 _Link_type __n = _M_new_node(__V, &_M_header);
1274 ++_M_count;
1275 _M_set_root(__n);
1276 _M_set_leftmost(__n);
1277 _M_set_rightmost(__n);
1278 return iterator(__n);
1279 }
1280 return _M_insert(_M_get_root(), __V, 0);
1281 }
1282
1283 template <class _InputIterator>
1284 void insert(_InputIterator __first, _InputIterator __last) {
1285 for (; __first != __last; ++__first)
1286 this->insert(*__first);
1287 }
1288
1289 void
1290 insert(iterator __pos, size_type __n, const value_type& __x)
1291 {
1292 for (; __n > 0; --__n)
1293 this->insert(__pos, __x);
1294 }
1295
1296 template<typename _InputIterator>
1297 void
1298 insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
1299 for (; __first != __last; ++__first)
1300 this->insert(__pos, *__first);
1301 }
1302
1303 // Note: this uses the find() to location the item you want to erase.
1304 // find() compares by equivalence of location ONLY. See the comments
1305 // above find_exact() for why you may not want this.
1306 //
1307 // If you want to erase ANY item that has the same location as __V,
1308 // then use this function.
1309 //
1310 // If you want to erase a PARTICULAR item, and not any other item
1311 // that might happen to have the same location, then you should use
1312 // erase_exact().
1313 void
1315 const_iterator b = this->find(__V);
1316 this->erase(b);
1317 }
1318
1319 void
1321 this->erase(this->find_exact(__V));
1322 }
1323
1324 // note: kept as const because its easier to const-cast it away
1325 void
1327 {
1328 assert(__IT != this->end());
1329 _Link_const_type target = __IT.get_raw_node();
1330 _Link_const_type n = target;
1331 size_type level = 0;
1332 while ((n = _S_parent(n)) != &_M_header)
1333 ++level;
1334 _M_erase( const_cast<_Link_type>(target), level );
1335 _M_delete_node( const_cast<_Link_type>(target) );
1336 --_M_count;
1337 }
1338
1339 /* this does not work since erasure changes sort order
1340 void
1341 erase(const_iterator __A, const_iterator const& __B)
1342 {
1343 if (0 && __A == this->begin() && __B == this->end())
1344 {
1345 this->clear();
1346 }
1347 else
1348 {
1349 while (__A != __B)
1350 this->erase(__A++);
1351 }
1352 }
1353*/
1354
1355 // compares via equivalence
1356 // so if you are looking for any item with the same location,
1357 // according to the standard accessor comparisons,
1358 // then this is the function for you.
1359 template <class SearchVal>
1360 const_iterator
1361 find(SearchVal const& __V) const
1362 {
1363 if (!_M_get_root()) return this->end();
1364 return _M_find(_M_get_root(), __V, 0);
1365 }
1366
1367 // compares via equality
1368 // if you are looking for a particular item in the tree,
1369 // and (for example) it has an ID that is checked via an == comparison
1370 // e.g.
1371 // struct Item
1372 // {
1373 // size_type unique_id;
1374 // bool operator==(Item const& a, Item const& b) { return a.unique_id == b.unique_id; }
1375 // Location location;
1376 // };
1377 // Two items may be equivalent in location. find() would return
1378 // either one of them. But no two items have the same ID, so
1379 // find_exact() would always return the item with the same location AND id.
1380 //
1381 template <class SearchVal>
1382 const_iterator
1383 find_exact(SearchVal const& __V) const
1384 {
1385 if (!_M_get_root()) return this->end();
1386 return _M_find_exact(_M_get_root(), __V, 0);
1387 }
1388
1389 // NOTE: see notes on find_within_range().
1390 size_type
1392 {
1393 if (!_M_get_root()) return 0;
1394 _Region_ __region(__V, __R, _M_acc, _M_cmp);
1395 return this->count_within_range(__region);
1396 }
1397
1398 size_type
1399 count_within_range(_Region_ const& __REGION) const
1400 {
1401 if (!_M_get_root()) return 0;
1402
1403 _Region_ __bounds(__REGION);
1404 return _M_count_within_range(_M_get_root(),
1405 __REGION, __bounds, 0);
1406 }
1407
1408 // NOTE: see notes on find_within_range().
1409 template <typename SearchVal, class Visitor>
1410 Visitor
1411 visit_within_range(SearchVal const& V, subvalue_type const R, Visitor visitor) const
1412 {
1413 if (!_M_get_root()) return visitor;
1414 _Region_ region(V, R, _M_acc, _M_cmp);
1415 return this->visit_within_range(region, visitor);
1416 }
1417
1418 template <class Visitor>
1419 Visitor
1420 visit_within_range(_Region_ const& REGION, Visitor visitor) const
1421 {
1422 if (_M_get_root())
1423 {
1424 _Region_ bounds(REGION);
1425 return _M_visit_within_range(visitor, _M_get_root(), REGION, bounds, 0);
1426 }
1427 return visitor;
1428 }
1429
1430 // NOTE: this will visit points based on 'Manhattan distance' aka city-block distance
1431 // aka taxicab metric. Meaning it will find all points within:
1432 // max(x_dist,max(y_dist,z_dist));
1433 // AND NOT than what you would expect: sqrt(x_dist*x_dist + y_dist*y_dist + z_dist*z_dist)
1434 //
1435 // This is because it converts the distance into a bounding-box 'region' and compares
1436 // against that.
1437 //
1438 // If you want the sqrt() behaviour, ask on the mailing list for different options.
1439 //
1440 template <typename SearchVal, typename _OutputIterator>
1441 _OutputIterator
1442 find_within_range(SearchVal const& val, subvalue_type const range,
1443 _OutputIterator out) const
1444 {
1445 if (!_M_get_root()) return out;
1446 _Region_ region(val, range, _M_acc, _M_cmp);
1447 return this->find_within_range(region, out);
1448 }
1449
1450 template <typename _OutputIterator>
1451 _OutputIterator
1453 _OutputIterator out) const
1454 {
1455 if (_M_get_root())
1456 {
1457 _Region_ bounds(region);
1458 out = _M_find_within_range(out, _M_get_root(),
1459 region, bounds, 0);
1460 }
1461 return out;
1462 }
1463
1464 template <class SearchVal>
1465 std::pair<const_iterator, distance_type>
1466 find_nearest (SearchVal const& __val) const
1467 {
1468 if (_M_get_root())
1469 {
1470 std::pair<const _Node<_Val>*,
1471 std::pair<size_type, typename _Acc::result_type> >
1472 best = _S_node_nearest (__K, 0, __val,
1473 _M_get_root(), &_M_header, _M_get_root(),
1475 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)),
1476 _M_cmp, _M_acc, _M_dist,
1478 return std::pair<const_iterator, distance_type>
1479 (best.first, best.second.second);
1480 }
1481 return std::pair<const_iterator, distance_type>(end(), 0);
1482 }
1483
1484 template <class SearchVal>
1485 std::pair<const_iterator, distance_type>
1486 find_nearest (SearchVal const& __val, distance_type __max) const
1487 {
1488 if (_M_get_root())
1489 {
1490 bool root_is_candidate = false;
1491 const _Node<_Val>* node = _M_get_root();
1492 { // scope to ensure we don't use 'root_dist' anywhere else
1493 distance_type root_dist = std::sqrt(_S_accumulate_node_distance
1494 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
1495 if (root_dist <= __max)
1496 {
1497 root_is_candidate = true;
1498 __max = root_dist;
1499 }
1500 }
1501 std::pair<const _Node<_Val>*,
1502 std::pair<size_type, typename _Acc::result_type> >
1503 best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
1504 node, __max, _M_cmp, _M_acc, _M_dist,
1506 // make sure we didn't just get stuck with the root node...
1507 if (root_is_candidate || best.first != _M_get_root())
1508 return std::pair<const_iterator, distance_type>
1509 (best.first, best.second.second);
1510 }
1511 return std::pair<const_iterator, distance_type>(end(), __max);
1512 }
1513
1514 template <class SearchVal, class _Predicate>
1515 std::pair<const_iterator, distance_type>
1516 find_nearest_if (SearchVal const& __val, distance_type __max,
1517 _Predicate __p) const
1518 {
1519 if (_M_get_root())
1520 {
1521 bool root_is_candidate = false;
1522 const _Node<_Val>* node = _M_get_root();
1523 if (__p(_M_get_root()->_M_value))
1524 {
1525 { // scope to ensure we don't use root_dist anywhere else
1526 distance_type root_dist = std::sqrt(_S_accumulate_node_distance
1527 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
1528 if (root_dist <= __max)
1529 {
1530 root_is_candidate = true;
1531 root_dist = __max;
1532 }
1533 }
1534 }
1535 std::pair<const _Node<_Val>*,
1536 std::pair<size_type, typename _Acc::result_type> >
1537 best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
1538 node, __max, _M_cmp, _M_acc, _M_dist, __p);
1539 // make sure we didn't just get stuck with the root node...
1540 if (root_is_candidate || best.first != _M_get_root())
1541 return std::pair<const_iterator, distance_type>
1542 (best.first, best.second.second);
1543 }
1544 return std::pair<const_iterator, distance_type>(end(), __max);
1545 }
1546
1547 void
1549 {
1550 std::vector<value_type> __v(this->begin(),this->end());
1551 this->clear();
1552 _M_optimise(__v.begin(), __v.end(), 0);
1553 }
1554
1555 void
1557 { // cater for people who cannot spell :)
1558 this->optimise();
1559 }
1560
1562 {
1563 _M_check_node(_M_get_root(),0);
1564 }
1565
1566protected:
1567
1568 void _M_check_children( _Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left )
1569 {
1570 assert(parent);
1571 if (child)
1572 {
1573 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1574 // REMEMBER! its a <= relationship for BOTH branches
1575 // for left-case (true), child<=node --> !(node<child)
1576 // for right-case (false), node<=child --> !(child<node)
1577 assert(!to_the_left || !compare(parent->_M_value,child->_M_value)); // check the left
1578 assert(to_the_left || !compare(child->_M_value,parent->_M_value)); // check the right
1579 // and recurse down the tree, checking everything
1580 _M_check_children(_S_left(child),parent,level,to_the_left);
1581 _M_check_children(_S_right(child),parent,level,to_the_left);
1582 }
1583 }
1584
1585 void _M_check_node( _Link_const_type node, size_type const level )
1586 {
1587 if (node)
1588 {
1589 // (comparing on this level)
1590 // everything to the left of this node must be smaller than this
1591 _M_check_children( _S_left(node), node, level, true );
1592 // everything to the right of this node must be larger than this
1593 _M_check_children( _S_right(node), node, level, false );
1594
1595 _M_check_node( _S_left(node), level+1 );
1596 _M_check_node( _S_right(node), level+1 );
1597 }
1598 }
1599
1601 {
1602 _M_set_leftmost(&_M_header);
1603 _M_set_rightmost(&_M_header);
1604 _M_header._M_parent = nullptr;
1605 _M_set_root(nullptr);
1606 }
1607
1608 iterator
1610 {
1611 _S_set_left(__N, _M_new_node(__V)); ++_M_count;
1612 _S_set_parent( _S_left(__N), __N );
1613 if (__N == _M_get_leftmost())
1614 _M_set_leftmost( _S_left(__N) );
1615 return iterator(_S_left(__N));
1616 }
1617
1618 iterator
1620 {
1621 _S_set_right(__N, _M_new_node(__V)); ++_M_count;
1622 _S_set_parent( _S_right(__N), __N );
1623 if (__N == _M_get_rightmost())
1624 _M_set_rightmost( _S_right(__N) );
1625 return iterator(_S_right(__N));
1626 }
1627
1628 iterator
1630 size_type const __L)
1631 {
1632 if (_Node_compare_(__L % __K, _M_acc, _M_cmp)(__V, __N->_M_value))
1633 {
1634 if (!_S_left(__N))
1635 return _M_insert_left(__N, __V);
1636 return _M_insert(_S_left(__N), __V, __L+1);
1637 }
1638 else
1639 {
1640 if (!_S_right(__N) || __N == _M_get_rightmost())
1641 return _M_insert_right(__N, __V);
1642 return _M_insert(_S_right(__N), __V, __L+1);
1643 }
1644 }
1645
1646 _Link_type
1647 _M_erase(_Link_type dead_dad, size_type const level)
1648 {
1649 // find a new step_dad, he will become a drop-in replacement.
1650 _Link_type step_dad = _M_get_erase_replacement(dead_dad, level);
1651
1652 // tell dead_dad's parent that his new child is step_dad
1653 if (dead_dad == _M_get_root())
1654 _M_set_root(step_dad);
1655 else if (_S_left(_S_parent(dead_dad)) == dead_dad)
1656 _S_set_left(_S_parent(dead_dad), step_dad);
1657 else
1658 _S_set_right(_S_parent(dead_dad), step_dad);
1659
1660 // deal with the left and right edges of the tree...
1661 // if the dead_dad was at the edge, then substitute...
1662 // but if there IS no new dead, then left_most is the dead_dad's parent
1663 if (dead_dad == _M_get_leftmost())
1664 _M_set_leftmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
1665 if (dead_dad == _M_get_rightmost())
1666 _M_set_rightmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
1667
1668 if (step_dad)
1669 {
1670 // step_dad gets dead_dad's parent
1671 _S_set_parent(step_dad, _S_parent(dead_dad));
1672
1673 // first tell the children that step_dad is their new dad
1674 if (_S_left(dead_dad))
1675 _S_set_parent(_S_left(dead_dad), step_dad);
1676 if (_S_right(dead_dad))
1677 _S_set_parent(_S_right(dead_dad), step_dad);
1678
1679 // step_dad gets dead_dad's children
1680 _S_set_left(step_dad, _S_left(dead_dad));
1681 _S_set_right(step_dad, _S_right(dead_dad));
1682 }
1683
1684 return step_dad;
1685 }
1686
1687
1688
1689 _Link_type
1691 {
1692 // if 'node' is null, then we can't do any better
1693 if (_S_is_leaf(node))
1694 return NULL;
1695
1696 std::pair<_Link_type,size_type> candidate;
1697 // if there is nothing to the left, find a candidate on the right tree
1698 if (!_S_left(node))
1699 candidate = _M_get_j_min( std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
1700 // ditto for the right
1701 else if ((!_S_right(node)))
1702 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
1703 // we have both children ...
1704 else
1705 {
1706 // we need to do a little more work in order to find a good candidate
1707 // this is actually a technique used to choose a node from either the
1708 // left or right branch RANDOMLY, so that the tree has a greater change of
1709 // staying balanced.
1710 // If this were a true binary tree, we would always hunt down the right branch.
1711 // See top for notes.
1712 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1713 // compare the children based on this level's criteria...
1714 // (this gives virtually random results)
1715 if (compare(_S_right(node)->_M_value, _S_left(node)->_M_value))
1716 // the right is smaller, get our replacement from the SMALLEST on the right
1717 candidate = _M_get_j_min(std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
1718 else
1719 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
1720 }
1721
1722 // we have a candidate replacement by now.
1723 // remove it from the tree, but don't delete it.
1724 // it must be disconnected before it can be reconnected.
1725 _Link_type parent = _S_parent(candidate.first);
1726 if (_S_left(parent) == candidate.first)
1727 _S_set_left(parent, _M_erase(candidate.first, candidate.second));
1728 else
1729 _S_set_right(parent, _M_erase(candidate.first, candidate.second));
1730
1731 return candidate.first;
1732 }
1733
1734
1735
1736 // TODO: why not pass node by const-ref?
1737 std::pair<_Link_type,size_type>
1738 _M_get_j_min( std::pair<_Link_type,size_type> const node, size_type const level)
1739 {
1740 typedef std::pair<_Link_type,size_type> Result;
1741 if (_S_is_leaf(node.first))
1742 return Result(node.first,level);
1743
1744 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
1745 Result candidate = node;
1746 if (_S_left(node.first))
1747 {
1748 Result left = _M_get_j_min(Result(_S_left(node.first), node.second), level+1);
1749 if (compare(left.first->_M_value, candidate.first->_M_value))
1750 candidate = left;
1751 }
1752 if (_S_right(node.first))
1753 {
1754 Result right = _M_get_j_min( Result(_S_right(node.first),node.second), level+1);
1755 if (compare(right.first->_M_value, candidate.first->_M_value))
1756 candidate = right;
1757 }
1758 if (candidate.first == node.first)
1759 return Result(candidate.first,level);
1760
1761 return candidate;
1762 }
1763
1764
1765
1766 // TODO: why not pass node by const-ref?
1767 std::pair<_Link_type,size_type>
1768 _M_get_j_max( std::pair<_Link_type,size_type> const node, size_type const level)
1769 {
1770 typedef std::pair<_Link_type,size_type> Result;
1771
1772 if (_S_is_leaf(node.first))
1773 return Result(node.first,level);
1774
1775 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
1776 Result candidate = node;
1777 if (_S_left(node.first))
1778 {
1779 Result left = _M_get_j_max( Result(_S_left(node.first),node.second), level+1);
1780 if (compare(candidate.first->_M_value, left.first->_M_value))
1781 candidate = left;
1782 }
1783 if (_S_right(node.first))
1784 {
1785 Result right = _M_get_j_max(Result(_S_right(node.first),node.second), level+1);
1786 if (compare(candidate.first->_M_value, right.first->_M_value))
1787 candidate = right;
1788 }
1789
1790 if (candidate.first == node.first)
1791 return Result(candidate.first,level);
1792
1793 return candidate;
1794 }
1795
1796
1797 void
1799 {
1800 while (__n)
1801 {
1802 _M_erase_subtree(_S_right(__n));
1803 _Link_type __t = _S_left(__n);
1804 _M_delete_node(__n);
1805 __n = __t;
1806 }
1807 }
1808
1809 const_iterator
1810 _M_find(_Link_const_type node, const_reference value, size_type const level) const
1811 {
1812 // be aware! This is very different to normal binary searches, because of the <=
1813 // relationship used. See top for notes.
1814 // Basically we have to check ALL branches, as we may have an identical node
1815 // in different branches.
1816 const_iterator found = this->end();
1817
1818 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1819 if (!compare(node->_M_value,value)) // note, this is a <= test
1820 {
1821 // this line is the only difference between _M_find_exact() and _M_find()
1822 if (_M_matches_node(node, value, level))
1823 return const_iterator(node); // return right away
1824 if (_S_left(node))
1825 found = _M_find(_S_left(node), value, level+1);
1826 }
1827 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
1828 found = _M_find(_S_right(node), value, level+1);
1829 return found;
1830 }
1831
1832 const_iterator
1834 {
1835 // be aware! This is very different to normal binary searches, because of the <=
1836 // relationship used. See top for notes.
1837 // Basically we have to check ALL branches, as we may have an identical node
1838 // in different branches.
1839 const_iterator found = this->end();
1840
1841 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1842 if (!compare(node->_M_value,value)) // note, this is a <= test
1843 {
1844 // this line is the only difference between _M_find_exact() and _M_find()
1845 if (value == *const_iterator(node))
1846 return const_iterator(node); // return right away
1847 if (_S_left(node))
1848 found = _M_find_exact(_S_left(node), value, level+1);
1849 }
1850
1851 // note: no else! items that are identical can be down both branches
1852 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
1853 found = _M_find_exact(_S_right(node), value, level+1);
1854 return found;
1855 }
1856
1857 bool
1859 size_type const __L) const
1860 {
1861 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1862 return !(compare(__N->_M_value, __V) || compare(__V, __N->_M_value));
1863 }
1864
1865 bool
1867 size_type const __L = 0) const
1868 {
1869 size_type __i = __L;
1870 while ((__i = (__i + 1) % __K) != __L % __K)
1871 if (!_M_matches_node_in_d(__N, __V, __i)) return false;
1872 return true;
1873 }
1874
1875 bool
1877 size_type __L = 0) const
1878 {
1879 return _M_matches_node_in_d(__N, __V, __L)
1880 && _M_matches_node_in_other_ds(__N, __V, __L);
1881 }
1882
1883 size_type
1885 _Region_ const& __BOUNDS,
1886 size_type const __L) const
1887 {
1888 size_type count = 0;
1889 if (__REGION.encloses(_S_value(__N)))
1890 {
1891 ++count;
1892 }
1893 if (_S_left(__N))
1894 {
1895 _Region_ __bounds(__BOUNDS);
1896 __bounds.set_high_bound(_S_value(__N), __L);
1897 if (__REGION.intersects_with(__bounds))
1898 count += _M_count_within_range(_S_left(__N),
1899 __REGION, __bounds, __L+1);
1900 }
1901 if (_S_right(__N))
1902 {
1903 _Region_ __bounds(__BOUNDS);
1904 __bounds.set_low_bound(_S_value(__N), __L);
1905 if (__REGION.intersects_with(__bounds))
1906 count += _M_count_within_range(_S_right(__N),
1907 __REGION, __bounds, __L+1);
1908 }
1909
1910 return count;
1911 }
1912
1913
1914 template <class Visitor>
1915 Visitor
1916 _M_visit_within_range(Visitor visitor,
1917 _Link_const_type N, _Region_ const& REGION,
1918 _Region_ const& BOUNDS,
1919 size_type const L) const
1920 {
1921 if (REGION.encloses(_S_value(N)))
1922 {
1923 visitor(_S_value(N));
1924 }
1925 if (_S_left(N))
1926 {
1927 _Region_ bounds(BOUNDS);
1928 bounds.set_high_bound(_S_value(N), L);
1929 if (REGION.intersects_with(bounds))
1930 visitor = _M_visit_within_range(visitor, _S_left(N),
1931 REGION, bounds, L+1);
1932 }
1933 if (_S_right(N))
1934 {
1935 _Region_ bounds(BOUNDS);
1936 bounds.set_low_bound(_S_value(N), L);
1937 if (REGION.intersects_with(bounds))
1938 visitor = _M_visit_within_range(visitor, _S_right(N),
1939 REGION, bounds, L+1);
1940 }
1941
1942 return visitor;
1943 }
1944
1945
1946
1947 template <typename _OutputIterator>
1948 _OutputIterator
1949 _M_find_within_range(_OutputIterator out,
1950 _Link_const_type __N, _Region_ const& __REGION,
1951 _Region_ const& __BOUNDS,
1952 size_type const __L) const
1953 {
1954 if (__REGION.encloses(_S_value(__N)))
1955 {
1956 *out++ = _S_value(__N);
1957 }
1958 if (_S_left(__N))
1959 {
1960 _Region_ __bounds(__BOUNDS);
1961 __bounds.set_high_bound(_S_value(__N), __L);
1962 if (__REGION.intersects_with(__bounds))
1963 out = _M_find_within_range(out, _S_left(__N),
1964 __REGION, __bounds, __L+1);
1965 }
1966 if (_S_right(__N))
1967 {
1968 _Region_ __bounds(__BOUNDS);
1969 __bounds.set_low_bound(_S_value(__N), __L);
1970 if (__REGION.intersects_with(__bounds))
1971 out = _M_find_within_range(out, _S_right(__N),
1972 __REGION, __bounds, __L+1);
1973 }
1974
1975 return out;
1976 }
1977
1978
1979 template <typename _Iter>
1980 void
1981 _M_optimise(_Iter const& __A, _Iter const& __B,
1982 size_type const __L)
1983 {
1984 if (__A == __B) return;
1985 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1986 _Iter __m = __A + (__B - __A) / 2;
1987 std::nth_element(__A, __m, __B, compare);
1988 this->insert(*__m);
1989 if (__m != __A) _M_optimise(__A, __m, __L+1);
1990 if (++__m != __B) _M_optimise(__m, __B, __L+1);
1991 }
1992
1993 _Link_const_type
1995 {
1996 return const_cast<_Link_const_type>(_M_root);
1997 }
1998
1999 _Link_type
2001 {
2002 return _M_root;
2003 }
2004
2006 {
2007 _M_root = n;
2008 }
2009
2010 _Link_const_type
2012 {
2013 return static_cast<_Link_type>(_M_header._M_left);
2014 }
2015
2016 void
2018 {
2019 _M_header._M_left = a;
2020 }
2021
2022 _Link_const_type
2024 {
2025 return static_cast<_Link_type>( _M_header._M_right );
2026 }
2027
2028 void
2030 {
2031 _M_header._M_right = a;
2032 }
2033
2034 static _Link_type
2036 {
2037 return static_cast<_Link_type>( N->_M_parent );
2038 }
2039
2040 static _Link_const_type
2042 {
2043 return static_cast<_Link_const_type>( N->_M_parent );
2044 }
2045
2046 static void
2048 {
2049 N->_M_parent = p;
2050 }
2051
2052 static void
2054 {
2055 N->_M_left = l;
2056 }
2057
2058 static _Link_type
2060 {
2061 return static_cast<_Link_type>( N->_M_left );
2062 }
2063
2064 static _Link_const_type
2066 {
2067 return static_cast<_Link_const_type>( N->_M_left );
2068 }
2069
2070 static void
2072 {
2073 N->_M_right = r;
2074 }
2075
2076 static _Link_type
2078 {
2079 return static_cast<_Link_type>( N->_M_right );
2080 }
2081
2082 static _Link_const_type
2084 {
2085 return static_cast<_Link_const_type>( N->_M_right );
2086 }
2087
2088 static bool
2090 {
2091 return !_S_left(N) && !_S_right(N);
2092 }
2093
2094 static const_reference
2096 {
2097 return N->_M_value;
2098 }
2099
2100 static const_reference
2102 {
2103 return static_cast<_Link_const_type>(N)->_M_value;
2104 }
2105
2106 static _Link_const_type
2108 {
2109 return static_cast<_Link_const_type> ( _Node_base::_S_minimum(__X) );
2110 }
2111
2112 static _Link_const_type
2114 {
2115 return static_cast<_Link_const_type>( _Node_base::_S_maximum(__X) );
2116 }
2117
2118
2119 _Link_type
2120 _M_new_node(const_reference __V, // = value_type(),
2121 _Base_ptr const __PARENT = nullptr,
2122 _Base_ptr const __LEFT = nullptr,
2123 _Base_ptr const __RIGHT = nullptr)
2124 {
2125 typename _Base::NoLeakAlloc noleak(this);
2126 _Link_type new_node = noleak.get();
2127 _Base::_M_construct_node(new_node, __V, __PARENT, __LEFT, __RIGHT);
2128 noleak.disconnect();
2129 return new_node;
2130 }
2131
2132 /* WHAT was this for?
2133 _Link_type
2134 _M_clone_node(_Link_const_type __X)
2135 {
2136 _Link_type __ret = _M_allocate_node(__X->_M_value);
2137 // TODO
2138 return __ret;
2139 }
2140 */
2141
2142 void
2144 {
2145 _Base::_M_destroy_node(__p);
2146 _Base::_M_deallocate_node(__p);
2147 }
2148
2154 _Dist _M_dist;
2155
2156#ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
2157 friend std::ostream&
2158 operator<<(std::ostream& o,
2160 {
2161 o << "meta node: " << tree._M_header << std::endl;
2162 o << "root node: " << tree._M_root << std::endl;
2163
2164 if (tree.empty())
2165 return o << "[empty " << __K << "d-tree " << &tree << "]";
2166
2167 o << "nodes total: " << tree.size() << std::endl;
2168 o << "dimensions: " << __K << std::endl;
2169
2171 typedef typename _Tree::_Link_type _Link_type;
2172
2173 std::stack<_Link_const_type> s;
2174 s.push(tree._M_get_root());
2175
2176 while (!s.empty())
2177 {
2178 _Link_const_type n = s.top();
2179 s.pop();
2180 o << *n << std::endl;
2181 if (_Tree::_S_left(n)) s.push(_Tree::_S_left(n));
2182 if (_Tree::_S_right(n)) s.push(_Tree::_S_right(n));
2183 }
2184
2185 return o;
2186 }
2187#endif
2188
2189};
2190
2191
2192} // namespace KDTree
2193
2194#endif // include guard
2195
2196/* COPYRIGHT --
2197 *
2198 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
2199 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
2200 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
2201 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
2202 * root for more information.
2203 * Parts of this file are (c) 2004-2007 Paul Harris <paulharris@computer.org>.
2204 *
2205 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2206 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
2207 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2208 */
Definition KDTree.h:1054
static _Link_type _S_left(_Base_ptr N)
Definition KDTree.h:2059
KDTree(const KDTree &__x)
Definition KDTree.h:1086
bool _M_matches_node_in_other_ds(_Link_const_type __N, const_reference __V, size_type const __L=0) const
Definition KDTree.h:1866
iterator insert(iterator, const_reference __V)
Definition KDTree.h:1263
_OutputIterator find_within_range(SearchVal const &val, subvalue_type const range, _OutputIterator out) const
Definition KDTree.h:1442
bool _M_matches_node_in_d(_Link_const_type __N, const_reference __V, size_type const __L) const
Definition KDTree.h:1858
const_reverse_iterator rend() const
Definition KDTree.h:1260
void efficient_replace_and_optimise(std::vector< value_type > &writable_vector)
Definition KDTree.h:1144
void erase_exact(const_reference __V)
Definition KDTree.h:1320
const _Dist & value_distance() const
Distance calculator between 2 value's element.
Definition KDTree.h:1240
void erase(const_reference __V)
Definition KDTree.h:1314
std::pair< const_iterator, distance_type > find_nearest(SearchVal const &__val, distance_type __max) const
Definition KDTree.h:1486
_Node_compare< _Val, _Acc, _Cmp > _Node_compare_
Definition KDTree.h:1064
bool _M_matches_node(_Link_const_type __N, const_reference __V, size_type __L=0) const
Definition KDTree.h:1876
static _Link_const_type _S_maximum(_Link_const_type __X)
Definition KDTree.h:2113
Visitor visit_within_range(_Region_ const &REGION, Visitor visitor) const
Definition KDTree.h:1420
_Link_const_type _M_get_rightmost() const
Definition KDTree.h:2023
iterator _M_insert_left(_Link_type __N, const_reference __V)
Definition KDTree.h:1609
static void _S_set_parent(_Base_ptr N, _Base_ptr p)
Definition KDTree.h:2047
value_type const * const_pointer
Definition KDTree.h:1070
void check_tree()
Definition KDTree.h:1561
static _Link_const_type _S_minimum(_Link_const_type __X)
Definition KDTree.h:2107
static void _S_set_left(_Base_ptr N, _Base_ptr l)
Definition KDTree.h:2053
const_iterator begin() const
Definition KDTree.h:1257
void _M_set_root(_Link_type n)
Definition KDTree.h:2005
_Link_type _M_get_root()
Definition KDTree.h:2000
iterator _M_insert(_Link_type __N, const_reference __V, size_type const __L)
Definition KDTree.h:1629
void optimise()
Definition KDTree.h:1548
void _M_delete_node(_Link_type __p)
Definition KDTree.h:2143
_OutputIterator _M_find_within_range(_OutputIterator out, _Link_const_type __N, _Region_ const &__REGION, _Region_ const &__BOUNDS, size_type const __L) const
Definition KDTree.h:1949
_Node< _Val > const * _Link_const_type
Definition KDTree.h:1062
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition KDTree.h:1251
_Link_type _M_get_erase_replacement(_Link_type node, size_type const level)
Definition KDTree.h:1690
static _Link_const_type _S_parent(_Base_const_ptr N)
Definition KDTree.h:2041
size_t size_type
Definition KDTree.h:1075
size_type count_within_range(const_reference __V, subvalue_type const __R) const
Definition KDTree.h:1391
std::pair< _Link_type, size_type > _M_get_j_max(std::pair< _Link_type, size_type > const node, size_type const level)
Definition KDTree.h:1768
_Node_base * _Base_ptr
Definition KDTree.h:1059
void _M_empty_initialise()
Definition KDTree.h:1600
size_type size() const
Definition KDTree.h:1188
_Dist _M_dist
Definition KDTree.h:2154
bool empty() const
Definition KDTree.h:1200
void _M_erase_subtree(_Link_type __n)
Definition KDTree.h:1798
_Node< _Val > * _Link_type
Definition KDTree.h:1061
value_type const & const_reference
Definition KDTree.h:1072
allocator_type get_allocator() const
Definition KDTree.h:1182
_Link_type _M_erase(_Link_type dead_dad, size_type const level)
Definition KDTree.h:1647
size_type _M_count_within_range(_Link_const_type __N, _Region_ const &__REGION, _Region_ const &__BOUNDS, size_type const __L) const
Definition KDTree.h:1884
iterator insert(const_reference __V)
Definition KDTree.h:1269
static _Link_const_type _S_right(_Base_const_ptr N)
Definition KDTree.h:2083
Visitor visit_within_range(SearchVal const &V, subvalue_type const R, Visitor visitor) const
Definition KDTree.h:1411
const_iterator find(SearchVal const &__V) const
Definition KDTree.h:1361
void _M_check_node(_Link_const_type node, size_type const level)
Definition KDTree.h:1585
_Dist & value_distance()
Definition KDTree.h:1244
void insert(iterator __pos, _InputIterator __first, _InputIterator __last)
Definition KDTree.h:1298
KDTree & operator=(const KDTree &__x)
Definition KDTree.h:1153
_Node_base _M_header
Definition KDTree.h:2150
void _M_optimise(_Iter const &__A, _Iter const &__B, size_type const __L)
Definition KDTree.h:1981
size_type count_within_range(_Region_ const &__REGION) const
Definition KDTree.h:1399
_Base::allocator_type allocator_type
Definition KDTree.h:1057
std::pair< _Link_type, size_type > _M_get_j_min(std::pair< _Link_type, size_type > const node, size_type const level)
Definition KDTree.h:1738
std::reverse_iterator< iterator > reverse_iterator
Definition KDTree.h:1252
size_type max_size() const
Definition KDTree.h:1194
~KDTree()
Definition KDTree.h:1176
_Alloc_base< _Val, _Alloc > _Base
Definition KDTree.h:1056
static _Link_const_type _S_left(_Base_const_ptr N)
Definition KDTree.h:2065
_Cmp value_comp() const
Comparator for the values in the KDTree.
Definition KDTree.h:1221
_Acc _M_acc
Definition KDTree.h:2152
void erase(const_iterator const &__IT)
Definition KDTree.h:1326
void insert(iterator __pos, size_type __n, const value_type &__x)
Definition KDTree.h:1290
void _M_set_leftmost(_Node_base *a)
Definition KDTree.h:2017
KDTree(_InputIterator __first, _InputIterator __last, _Acc const &acc=_Acc(), _Dist const &__dist=_Dist(), _Cmp const &__cmp=_Cmp(), const allocator_type &__a=allocator_type())
Definition KDTree.h:1106
void insert(_InputIterator __first, _InputIterator __last)
Definition KDTree.h:1284
void optimize()
Definition KDTree.h:1556
_Link_const_type _M_get_leftmost() const
Definition KDTree.h:2011
_Node_base const * _Base_const_ptr
Definition KDTree.h:1060
static bool _S_is_leaf(_Base_const_ptr N)
Definition KDTree.h:2089
std::pair< const_iterator, distance_type > find_nearest(SearchVal const &__val) const
Definition KDTree.h:1466
_Val value_type
Definition KDTree.h:1068
const_iterator _M_find(_Link_const_type node, const_reference value, size_type const level) const
Definition KDTree.h:1810
static const_reference _S_value(_Link_const_type N)
Definition KDTree.h:2095
std::pair< const_iterator, distance_type > find_nearest_if(SearchVal const &__val, distance_type __max, _Predicate __p) const
Definition KDTree.h:1516
value_type & reference
Definition KDTree.h:1071
void _M_check_children(_Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left)
Definition KDTree.h:1568
_Acc value_acc() const
Accessor to the value's elements.
Definition KDTree.h:1230
_Link_type _M_root
Definition KDTree.h:2149
Visitor _M_visit_within_range(Visitor visitor, _Link_const_type N, _Region_ const &REGION, _Region_ const &BOUNDS, size_type const L) const
Definition KDTree.h:1916
void clear()
Definition KDTree.h:1206
const_iterator iterator
Definition KDTree.h:1250
const_iterator end() const
Definition KDTree.h:1258
ptrdiff_t difference_type
Definition KDTree.h:1076
value_type * pointer
Definition KDTree.h:1069
size_type _M_count
Definition KDTree.h:2151
_Cmp _M_cmp
Definition KDTree.h:2153
_Iterator< _Val, const_reference, const_pointer > const_iterator
Definition KDTree.h:1248
iterator _M_insert_right(_Link_type __N, const_reference __V)
Definition KDTree.h:1619
static void _S_set_right(_Base_ptr N, _Base_ptr r)
Definition KDTree.h:2071
_Region< __K, _Val, typename _Acc::result_type, _Acc, _Cmp > _Region_
Definition KDTree.h:1067
KDTree(_Acc const &__acc=_Acc(), _Dist const &__dist=_Dist(), _Cmp const &__cmp=_Cmp(), const allocator_type &__a=allocator_type())
Definition KDTree.h:1078
_Link_type _M_new_node(const_reference __V, _Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition KDTree.h:2120
const_iterator find_exact(SearchVal const &__V) const
Definition KDTree.h:1383
_Link_const_type _M_get_root() const
Definition KDTree.h:1994
const_iterator _M_find_exact(_Link_const_type node, const_reference value, size_type const level) const
Definition KDTree.h:1833
const_reverse_iterator rbegin() const
Definition KDTree.h:1259
static _Link_type _S_parent(_Base_ptr N)
Definition KDTree.h:2035
void _M_set_rightmost(_Node_base *a)
Definition KDTree.h:2029
static _Link_type _S_right(_Base_ptr N)
Definition KDTree.h:2077
_Dist::distance_type distance_type
Definition KDTree.h:1074
_Acc::result_type subvalue_type
Definition KDTree.h:1073
_OutputIterator find_within_range(_Region_ const &region, _OutputIterator out) const
Definition KDTree.h:1452
static const_reference _S_value(_Base_const_ptr N)
Definition KDTree.h:2101
Definition KDTree.h:514
_Node_ * new_node
Definition KDTree.h:516
~NoLeakAlloc()
Definition KDTree.h:524
_Node_ * get()
Definition KDTree.h:521
void disconnect()
Definition KDTree.h:522
NoLeakAlloc(_Alloc_base *b)
Definition KDTree.h:519
_Alloc_base * base
Definition KDTree.h:515
Definition KDTree.h:497
_Node_::_Base_ptr _Base_ptr
Definition KDTree.h:500
void _M_construct_node(_Node_ *__p, _Tp const __V=_Tp(), _Base_ptr const __PARENT=NULL, _Base_ptr const __LEFT=NULL, _Base_ptr const __RIGHT=NULL)
Definition KDTree.h:544
_Node< _Tp > _Node_
Definition KDTree.h:499
_Alloc_base(allocator_type const &__A)
Definition KDTree.h:503
allocator_type get_allocator() const
Definition KDTree.h:507
void _M_deallocate_node(_Node_ *const __P)
Definition KDTree.h:538
_Alloc allocator_type
Definition KDTree.h:501
void _M_destroy_node(_Node_ *__p)
Definition KDTree.h:553
_Node_ * _M_allocate_node()
Definition KDTree.h:532
allocator_type _M_node_allocator
Definition KDTree.h:529
Definition KDTree.h:622
void _M_decrement()
Definition KDTree.h:655
_Base_iterator(_Base_iterator const &__THAT)
Definition KDTree.h:629
_Node_base::_Base_const_ptr _Base_const_ptr
Definition KDTree.h:624
_Base_const_ptr _M_node
Definition KDTree.h:625
_Base_iterator(_Base_const_ptr const __N=nullptr)
Definition KDTree.h:627
void _M_increment()
Definition KDTree.h:633
Definition KDTree.h:688
_Iterator< _Val, _Ref, _Ptr > _Self
Definition KDTree.h:695
std::bidirectional_iterator_tag iterator_category
Definition KDTree.h:697
_Iterator< _Val, _Val &, _Val * > iterator
Definition KDTree.h:693
_Ptr pointer
Definition KDTree.h:692
_Node< _Val > const * _Link_const_type
Definition KDTree.h:696
_Self operator++(int)
Definition KDTree.h:732
_Iterator(_Link_const_type const __N)
Definition KDTree.h:702
_Self & operator--()
Definition KDTree.h:740
_Link_const_type get_raw_node() const
Definition KDTree.h:707
_Iterator(iterator const &__THAT)
Definition KDTree.h:704
_Ref reference
Definition KDTree.h:691
_Self operator++()
Definition KDTree.h:725
_Iterator< _Val, _Val const &, _Val const * > const_iterator
Definition KDTree.h:694
reference operator*() const
Definition KDTree.h:713
_Val value_type
Definition KDTree.h:690
_Iterator()
Definition KDTree.h:700
ptrdiff_t difference_type
Definition KDTree.h:698
_Self operator--(int)
Definition KDTree.h:747
pointer operator->() const
Definition KDTree.h:719
Definition KDTree.h:125
bool operator()(_Val const &__A, _Val const &__B) const
Definition KDTree.h:131
_Node_compare(size_t const __DIM, _Acc const &acc, _Cmp const &cmp)
Definition KDTree.h:127
_Acc _M_acc
Definition KDTree.h:138
_Cmp _M_cmp
Definition KDTree.h:139
size_t _M_DIM
Definition KDTree.h:137
Definition KDTree.h:47
std::pair< const NodeType *, std::pair< size_t, typename _Dist::distance_type > > _S_node_nearest(const size_t __k, size_t __dim, SearchVal const &__val, const NodeType *__node, const _Node_base *__end, const NodeType *__best, typename _Dist::distance_type __max, const _Cmp &__cmp, const _Acc &__acc, const _Dist &__dist, _Predicate __p)
Definition KDTree.h:227
bool _S_node_compare(const size_t __dim, const _Cmp &__cmp, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition KDTree.h:152
bool operator==(_Iterator< _Val, _Ref, _Ptr > const &, _Iterator< _Val, _Ref, _Ptr > const &)
Definition KDTree.h:781
bool operator!=(_Iterator< _Val, _Ref, _Ptr > const &, _Iterator< _Val, _Ref, _Ptr > const &)
Definition KDTree.h:799
_Dist::distance_type _S_accumulate_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition KDTree.h:185
const NodeType * _S_node_descend(const size_t __dim, const _Cmp &__cmp, const _Acc &__acc, const _Val &__val, const NodeType *__node)
Definition KDTree.h:203
_Dist::distance_type _S_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition KDTree.h:168
Definition KDTree.h:408
result_type operator()(_Val const &V, size_t const N) const
Definition KDTree.h:412
_Val::value_type result_type
Definition KDTree.h:409
Definition KDTree.h:49
_Node_base * _Base_ptr
Definition KDTree.h:50
_Base_ptr _M_parent
Definition KDTree.h:53
static _Base_ptr _S_minimum(_Base_ptr __x)
Definition KDTree.h:63
_Base_ptr _M_right
Definition KDTree.h:55
_Node_base const * _Base_const_ptr
Definition KDTree.h:51
static _Base_ptr _S_maximum(_Base_ptr __x)
Definition KDTree.h:70
_Base_ptr _M_left
Definition KDTree.h:54
_Node_base(_Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition KDTree.h:57
Definition KDTree.h:79
_Node(_Val const &__VALUE=_Val(), _Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition KDTree.h:85
_Val _M_value
Definition KDTree.h:83
_Node * _Link_type
Definition KDTree.h:81
Definition KDTree.h:848
bool encloses(value_type const &__V) const
Definition KDTree.h:914
_Region & set_high_bound(value_type const &__V, size_t const __L)
Definition KDTree.h:926
bool intersects_with(_Region const &__THAT) const
Definition KDTree.h:902
_Region(_Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition KDTree.h:857
_Region & set_low_bound(value_type const &__V, size_t const __L)
Definition KDTree.h:933
_SubVal subvalue_type
Definition KDTree.h:850
_Region(Val const &__V, subvalue_type const &__R, _Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition KDTree.h:872
_Acc _M_acc
Definition KDTree.h:940
std::pair< _Region, _SubVal > _CenterPt
Definition KDTree.h:855
_Val value_type
Definition KDTree.h:849
subvalue_type _M_low_bounds[__K]
Definition KDTree.h:939
_Cmp _M_cmp
Definition KDTree.h:941
bool intersects_with(_CenterPt const &__THAT) const
Definition KDTree.h:884
subvalue_type _M_high_bounds[__K]
Definition KDTree.h:939
_Region(Val const &__V, _Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition KDTree.h:861
Definition KDTree.h:420
bool operator()(const _Tp &) const
Definition KDTree.h:421
Definition KDTree.h:439
distance_type operator()(const _Tp &__a, const _Tp &__b) const
Definition KDTree.h:454
long _M_count
Definition KDTree.h:462
long & count() const
Definition KDTree.h:450
squared_difference_counted()
Definition KDTree.h:442
void reset()
Definition KDTree.h:446
_Dist distance_type
Definition KDTree.h:440
Definition KDTree.h:426
distance_type operator()(const _Tp &__a, const _Tp &__b) const
Definition KDTree.h:430
_Dist distance_type
Definition KDTree.h:427