46 #ifndef INCLUDE_KDTREE_KDTREE_HPP 47 #define INCLUDE_KDTREE_KDTREE_HPP 56 #define KDTREE_VERSION 700 61 #define KDTREE_LIB_VERSION "0_7_0" 66 #ifdef KDTREE_CHECK_PERFORMANCE_COUNTERS 71 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS 89 #ifdef KDTREE_CHECK_PERFORMANCE 90 unsigned long long num_dist_calcs = 0;
93 template <
size_t const __K,
typename _Val,
94 typename _Acc = _Bracket_accessor<_Val>,
95 typename _Dist = squared_difference<
typename _Acc::result_type,
96 typename _Acc::result_type>,
97 typename _Cmp = std::less<typename _Acc::result_type>,
98 typename _Alloc = std::allocator<_Node<_Val> > >
103 typedef typename _Base::allocator_type allocator_type;
115 typedef _Val value_type;
116 typedef value_type* pointer;
117 typedef value_type
const* const_pointer;
118 typedef value_type& reference;
119 typedef value_type
const& const_reference;
120 typedef typename _Acc::result_type subvalue_type;
121 typedef typename _Dist::distance_type distance_type;
122 typedef size_t size_type;
123 typedef ptrdiff_t difference_type;
125 KDTree(_Acc
const& __acc = _Acc(), _Dist
const& __dist = _Dist(),
126 _Cmp
const& __cmp = _Cmp(),
const allocator_type& __a = allocator_type())
127 : _Base(__a), _M_header(),
128 _M_count(0), _M_acc(__acc), _M_cmp(__cmp), _M_dist(__dist)
130 _M_empty_initialise();
134 : _Base(__x.get_allocator()), _M_header(), _M_count(0),
135 _M_acc(__x._M_acc), _M_cmp(__x._M_cmp), _M_dist(__x._M_dist)
137 _M_empty_initialise();
146 std::vector<value_type> temp;
147 temp.reserve(__x.size());
148 std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
149 _M_optimise(temp.begin(), temp.end(), 0);
152 template<
typename _InputIterator>
153 KDTree(_InputIterator __first, _InputIterator __last,
154 _Acc
const& acc = _Acc(), _Dist
const& __dist = _Dist(),
155 _Cmp
const& __cmp = _Cmp(),
const allocator_type& __a = allocator_type())
156 : _Base(__a), _M_header(), _M_count(0),
157 _M_acc(acc), _M_cmp(__cmp), _M_dist(__dist)
159 _M_empty_initialise();
168 std::vector<value_type> temp;
169 temp.reserve(std::distance(__first,__last));
170 std::copy(__first,__last,std::back_inserter(temp));
171 _M_optimise(temp.begin(), temp.end(), 0);
191 void efficient_replace_and_optimise( std::vector<value_type> & writable_vector )
194 _M_optimise(writable_vector.begin(), writable_vector.end(), 0);
200 operator=(
const KDTree& __x)
205 _M_dist = __x._M_dist;
215 std::vector<value_type> temp;
216 temp.reserve(__x.size());
217 std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
218 efficient_replace_and_optimise(temp);
229 get_allocator()
const 231 return _Base::get_allocator();
243 return size_type(-1);
249 return this->size() == 0;
255 _M_erase_subtree(_M_get_root());
256 _M_set_leftmost(&_M_header);
257 _M_set_rightmost(&_M_header);
298 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
299 typedef std::reverse_iterator<iterator> reverse_iterator;
304 const_iterator begin()
const {
return const_iterator(_M_get_leftmost()); }
305 const_iterator end()
const {
return const_iterator(static_cast<_Link_const_type>(&_M_header)); }
306 const_reverse_iterator rbegin()
const {
return const_reverse_iterator(end()); }
307 const_reverse_iterator rend()
const {
return const_reverse_iterator(begin()); }
310 insert(iterator , const_reference __V)
312 return this->insert(__V);
316 insert(const_reference __V)
320 _Link_type __n = _M_new_node(__V, &_M_header);
323 _M_set_leftmost(__n);
324 _M_set_rightmost(__n);
325 return iterator(__n);
327 return _M_insert(_M_get_root(), __V, 0);
330 template <
class _InputIterator>
331 void insert(_InputIterator __first, _InputIterator __last) {
332 for (; __first != __last; ++__first)
333 this->insert(*__first);
337 insert(iterator __pos, size_type __n,
const value_type& __x)
339 for (; __n > 0; --__n)
340 this->insert(__pos, __x);
343 template<
typename _InputIterator>
345 insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
346 for (; __first != __last; ++__first)
347 this->insert(__pos, *__first);
361 erase(const_reference __V) {
362 const_iterator b = this->find(__V);
367 erase_exact(const_reference __V) {
368 this->erase(this->find_exact(__V));
373 erase(const_iterator
const& __IT)
375 assert(__IT != this->end());
376 _Link_const_type target = __IT.get_raw_node();
377 _Link_const_type n = target;
379 while ((n = _S_parent(n)) != &_M_header)
381 _M_erase( const_cast<_Link_type>(target), level );
382 _M_delete_node( const_cast<_Link_type>(target) );
406 template <
class SearchVal>
408 find(SearchVal
const& __V)
const 410 if (!_M_get_root())
return this->end();
411 return _M_find(_M_get_root(), __V, 0);
428 template <
class SearchVal>
430 find_exact(SearchVal
const& __V)
const 432 if (!_M_get_root())
return this->end();
433 return _M_find_exact(_M_get_root(), __V, 0);
437 count_within_range(const_reference __V, subvalue_type
const __R)
const 439 if (!_M_get_root())
return 0;
440 _Region_ __region(__V, __R, _M_acc, _M_cmp);
441 return this->count_within_range(__region);
445 count_within_range(_Region_
const& __REGION)
const 447 if (!_M_get_root())
return 0;
449 _Region_ __bounds(__REGION);
450 return _M_count_within_range(_M_get_root(),
451 __REGION, __bounds, 0);
454 template <
typename SearchVal,
class Visitor>
456 visit_within_range(SearchVal
const& V, subvalue_type
const R, Visitor visitor)
const 458 if (!_M_get_root())
return visitor;
459 _Region_ region(V, R, _M_acc, _M_cmp);
460 return this->visit_within_range(region, visitor);
463 template <
class Visitor>
465 visit_within_range(_Region_
const& REGION, Visitor visitor)
const 469 _Region_ bounds(REGION);
470 return _M_visit_within_range(visitor, _M_get_root(), REGION, bounds, 0);
476 find_within_range_iterative(const_reference __a, const_reference __b)
478 return const_iterator(begin());
481 template <
typename SearchVal,
typename _OutputIterator>
483 find_within_range(SearchVal
const& val, subvalue_type
const range,
484 _OutputIterator out)
const 486 if (!_M_get_root())
return out;
487 _Region_ region(val, range, _M_acc, _M_cmp);
488 return this->find_within_range(region, out);
491 template <
typename _OutputIterator>
493 find_within_range(_Region_
const& region,
494 _OutputIterator out)
const 498 _Region_ bounds(region);
499 out = _M_find_within_range(out, _M_get_root(),
505 template <
class SearchVal>
506 std::pair<const_iterator, distance_type>
507 find_nearest (SearchVal
const& __val)
const 511 std::pair<const _Node<_Val>*,
512 std::pair<size_type, typename _Acc::result_type> >
514 _M_get_root(), &_M_header, _M_get_root(),
516 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)),
517 _M_cmp, _M_acc, _M_dist,
519 return std::pair<const_iterator, distance_type>
520 (best.first, best.second.second);
522 return std::pair<const_iterator, distance_type>(end(), 0);
525 template <
class SearchVal>
526 std::pair<const_iterator, distance_type>
527 find_nearest (SearchVal
const& __val, distance_type __max)
const 531 bool root_is_candidate =
false;
535 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
536 if (root_dist <= __max)
538 root_is_candidate =
true;
542 std::pair<const _Node<_Val>*,
543 std::pair<size_type, typename _Acc::result_type> >
545 node, __max, _M_cmp, _M_acc, _M_dist,
548 if (root_is_candidate || best.first != _M_get_root())
549 return std::pair<const_iterator, distance_type>
550 (best.first, best.second.second);
552 return std::pair<const_iterator, distance_type>(end(), __max);
555 template <
class SearchVal,
class _Predicate>
556 std::pair<const_iterator, distance_type>
557 find_nearest_if (SearchVal
const& __val, distance_type __max,
558 _Predicate __p)
const 562 bool root_is_candidate =
false;
564 if (__p(_M_get_root()->_M_value))
568 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
569 if (root_dist <= __max)
571 root_is_candidate =
true;
576 std::pair<const _Node<_Val>*,
577 std::pair<size_type, typename _Acc::result_type> >
579 node, __max, _M_cmp, _M_acc, _M_dist, __p);
581 if (root_is_candidate || best.first != _M_get_root())
582 return std::pair<const_iterator, distance_type>
583 (best.first, best.second.second);
585 return std::pair<const_iterator, distance_type>(end(), __max);
591 std::vector<value_type> __v(this->begin(),this->end());
593 _M_optimise(__v.begin(), __v.end(), 0);
604 _M_check_node(_M_get_root(),0);
609 void _M_check_children( _Link_const_type child, _Link_const_type parent, size_type
const level,
bool to_the_left )
614 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
618 assert(!to_the_left || !compare(parent->_M_value,child->_M_value));
619 assert(to_the_left || !compare(child->_M_value,parent->_M_value));
621 _M_check_children(_S_left(child),parent,level,to_the_left);
622 _M_check_children(_S_right(child),parent,level,to_the_left);
626 void _M_check_node( _Link_const_type node, size_type
const level )
632 _M_check_children( _S_left(node), node, level,
true );
634 _M_check_children( _S_right(node), node, level,
false );
636 _M_check_node( _S_left(node), level+1 );
637 _M_check_node( _S_right(node), level+1 );
641 void _M_empty_initialise()
643 _M_set_leftmost(&_M_header);
644 _M_set_rightmost(&_M_header);
645 _M_header._M_parent = NULL;
650 _M_insert_left(_Link_type __N, const_reference __V)
652 _S_set_left(__N, _M_new_node(__V)); ++_M_count;
653 _S_set_parent( _S_left(__N), __N );
654 if (__N == _M_get_leftmost())
655 _M_set_leftmost( _S_left(__N) );
656 return iterator(_S_left(__N));
660 _M_insert_right(_Link_type __N, const_reference __V)
662 _S_set_right(__N, _M_new_node(__V)); ++_M_count;
663 _S_set_parent( _S_right(__N), __N );
664 if (__N == _M_get_rightmost())
665 _M_set_rightmost( _S_right(__N) );
666 return iterator(_S_right(__N));
670 _M_insert(_Link_type __N, const_reference __V,
673 if (_Node_compare_(__L % __K, _M_acc, _M_cmp)(__V, __N->_M_value))
676 return _M_insert_left(__N, __V);
677 return _M_insert(_S_left(__N), __V, __L+1);
681 if (!_S_right(__N) || __N == _M_get_rightmost())
682 return _M_insert_right(__N, __V);
683 return _M_insert(_S_right(__N), __V, __L+1);
688 _M_erase(_Link_type dead_dad, size_type
const level)
691 _Link_type step_dad = _M_get_erase_replacement(dead_dad, level);
694 if (dead_dad == _M_get_root())
695 _M_set_root(step_dad);
696 else if (_S_left(_S_parent(dead_dad)) == dead_dad)
697 _S_set_left(_S_parent(dead_dad), step_dad);
699 _S_set_right(_S_parent(dead_dad), step_dad);
704 if (dead_dad == _M_get_leftmost())
705 _M_set_leftmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
706 if (dead_dad == _M_get_rightmost())
707 _M_set_rightmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
712 _S_set_parent(step_dad, _S_parent(dead_dad));
715 if (_S_left(dead_dad))
716 _S_set_parent(_S_left(dead_dad), step_dad);
717 if (_S_right(dead_dad))
718 _S_set_parent(_S_right(dead_dad), step_dad);
721 _S_set_left(step_dad, _S_left(dead_dad));
722 _S_set_right(step_dad, _S_right(dead_dad));
731 _M_get_erase_replacement(_Link_type node, size_type
const level)
734 if (_S_is_leaf(node))
737 std::pair<_Link_type,size_type> candidate;
740 candidate = _M_get_j_min( std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
742 else if ((!_S_right(node)))
743 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
753 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
756 if (compare(_S_right(node)->_M_value, _S_left(node)->_M_value))
758 candidate = _M_get_j_min(std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
760 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
766 _Link_type parent = _S_parent(candidate.first);
767 if (_S_left(parent) == candidate.first)
768 _S_set_left(parent, _M_erase(candidate.first, candidate.second));
770 _S_set_right(parent, _M_erase(candidate.first, candidate.second));
772 return candidate.first;
777 std::pair<_Link_type,size_type>
778 _M_get_j_min( std::pair<_Link_type,size_type>
const node, size_type
const level)
780 typedef std::pair<_Link_type,size_type> Result;
781 if (_S_is_leaf(node.first))
782 return Result(node.first,level);
784 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
785 Result candidate = node;
786 if (_S_left(node.first))
788 Result left = _M_get_j_min(Result(_S_left(node.first), node.second), level+1);
789 if (compare(left.first->_M_value, candidate.first->_M_value))
792 if (_S_right(node.first))
794 Result right = _M_get_j_min( Result(_S_right(node.first),node.second), level+1);
795 if (compare(right.first->_M_value, candidate.first->_M_value))
798 if (candidate.first == node.first)
799 return Result(candidate.first,level);
806 std::pair<_Link_type,size_type>
807 _M_get_j_max( std::pair<_Link_type,size_type>
const node, size_type
const level)
809 typedef std::pair<_Link_type,size_type> Result;
811 if (_S_is_leaf(node.first))
812 return Result(node.first,level);
814 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
815 Result candidate = node;
816 if (_S_left(node.first))
818 Result left = _M_get_j_max( Result(_S_left(node.first),node.second), level+1);
819 if (compare(candidate.first->_M_value, left.first->_M_value))
822 if (_S_right(node.first))
824 Result right = _M_get_j_max(Result(_S_right(node.first),node.second), level+1);
825 if (compare(candidate.first->_M_value, right.first->_M_value))
829 if (candidate.first == node.first)
830 return Result(candidate.first,level);
837 _M_erase_subtree(_Link_type __n)
841 _M_erase_subtree(_S_right(__n));
842 _Link_type __t = _S_left(__n);
849 _M_find(_Link_const_type node, const_reference value, size_type
const level)
const 855 const_iterator found = this->end();
857 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
858 if (!compare(node->_M_value,value))
861 if (_M_matches_node(node, value, level))
862 return const_iterator(node);
864 found = _M_find(_S_left(node), value, level+1);
866 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value))
867 found = _M_find(_S_right(node), value, level+1);
872 _M_find_exact(_Link_const_type node, const_reference value, size_type
const level)
const 878 const_iterator found = this->end();
880 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
881 if (!compare(node->_M_value,value))
884 if (value == *const_iterator(node))
885 return const_iterator(node);
887 found = _M_find_exact(_S_left(node), value, level+1);
891 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value))
892 found = _M_find_exact(_S_right(node), value, level+1);
897 _M_matches_node_in_d(_Link_const_type __N, const_reference __V,
898 size_type
const __L)
const 900 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
901 return !(compare(__N->_M_value, __V) || compare(__V, __N->_M_value));
905 _M_matches_node_in_other_ds(_Link_const_type __N, const_reference __V,
906 size_type
const __L = 0)
const 909 while ((__i = (__i + 1) % __K) != __L % __K)
910 if (!_M_matches_node_in_d(__N, __V, __i))
return false;
915 _M_matches_node(_Link_const_type __N, const_reference __V,
916 size_type __L = 0)
const 918 return _M_matches_node_in_d(__N, __V, __L)
919 && _M_matches_node_in_other_ds(__N, __V, __L);
923 _M_count_within_range(_Link_const_type __N, _Region_
const& __REGION,
924 _Region_
const& __BOUNDS,
925 size_type
const __L)
const 928 if (__REGION.encloses(_S_value(__N)))
934 _Region_ __bounds(__BOUNDS);
935 __bounds.set_high_bound(_S_value(__N), __L);
936 if (__REGION.intersects_with(__bounds))
937 count += _M_count_within_range(_S_left(__N),
938 __REGION, __bounds, __L+1);
942 _Region_ __bounds(__BOUNDS);
943 __bounds.set_low_bound(_S_value(__N), __L);
944 if (__REGION.intersects_with(__bounds))
945 count += _M_count_within_range(_S_right(__N),
946 __REGION, __bounds, __L+1);
953 template <
class Visitor>
955 _M_visit_within_range(Visitor visitor,
956 _Link_const_type N, _Region_
const& REGION,
957 _Region_
const& BOUNDS,
958 size_type
const L)
const 960 if (REGION.encloses(_S_value(N)))
962 visitor(_S_value(N));
966 _Region_ bounds(BOUNDS);
967 bounds.set_high_bound(_S_value(N), L);
968 if (REGION.intersects_with(bounds))
969 visitor = _M_visit_within_range(visitor, _S_left(N),
970 REGION, bounds, L+1);
974 _Region_ bounds(BOUNDS);
975 bounds.set_low_bound(_S_value(N), L);
976 if (REGION.intersects_with(bounds))
977 visitor = _M_visit_within_range(visitor, _S_right(N),
978 REGION, bounds, L+1);
986 template <
typename _OutputIterator>
988 _M_find_within_range(_OutputIterator out,
989 _Link_const_type __N, _Region_
const& __REGION,
990 _Region_
const& __BOUNDS,
991 size_type
const __L)
const 993 if (__REGION.encloses(_S_value(__N)))
995 *out++ = _S_value(__N);
999 _Region_ __bounds(__BOUNDS);
1000 __bounds.set_high_bound(_S_value(__N), __L);
1001 if (__REGION.intersects_with(__bounds))
1002 out = _M_find_within_range(out, _S_left(__N),
1003 __REGION, __bounds, __L+1);
1007 _Region_ __bounds(__BOUNDS);
1008 __bounds.set_low_bound(_S_value(__N), __L);
1009 if (__REGION.intersects_with(__bounds))
1010 out = _M_find_within_range(out, _S_right(__N),
1011 __REGION, __bounds, __L+1);
1018 template <
typename _Iter>
1020 _M_optimise(_Iter
const& __A, _Iter
const& __B,
1021 size_type
const __L)
1023 if (__A == __B)
return;
1024 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1025 _Iter __m = __A + (__B - __A) / 2;
1026 std::nth_element(__A, __m, __B, compare);
1028 if (__m != __A) _M_optimise(__A, __m, __L+1);
1029 if (++__m != __B) _M_optimise(__m, __B, __L+1);
1035 return const_cast<_Link_const_type
>(_M_root);
1044 void _M_set_root(_Link_type n)
1050 _M_get_leftmost()
const 1052 return static_cast<_Link_type
>(_M_header._M_left);
1058 _M_header._M_left = a;
1062 _M_get_rightmost()
const 1064 return static_cast<_Link_type
>( _M_header._M_right );
1070 _M_header._M_right = a;
1074 _S_parent(_Base_ptr N)
1076 return static_cast<_Link_type
>( N->_M_parent );
1079 static _Link_const_type
1080 _S_parent(_Base_const_ptr N)
1082 return static_cast<_Link_const_type
>( N->_M_parent );
1086 _S_set_parent(_Base_ptr N, _Base_ptr p)
1092 _S_set_left(_Base_ptr N, _Base_ptr l)
1098 _S_left(_Base_ptr N)
1100 return static_cast<_Link_type
>( N->_M_left );
1103 static _Link_const_type
1104 _S_left(_Base_const_ptr N)
1106 return static_cast<_Link_const_type
>( N->_M_left );
1110 _S_set_right(_Base_ptr N, _Base_ptr r)
1116 _S_right(_Base_ptr N)
1118 return static_cast<_Link_type
>( N->_M_right );
1121 static _Link_const_type
1122 _S_right(_Base_const_ptr N)
1124 return static_cast<_Link_const_type
>( N->_M_right );
1128 _S_is_leaf(_Base_const_ptr N)
1130 return !_S_left(N) && !_S_right(N);
1133 static const_reference
1134 _S_value(_Link_const_type N)
1139 static const_reference
1140 _S_value(_Base_const_ptr N)
1142 return static_cast<_Link_const_type
>(N)->_M_value;
1145 static _Link_const_type
1146 _S_minimum(_Link_const_type __X)
1148 return static_cast<_Link_const_type
> ( _Node_base::_S_minimum(__X) );
1151 static _Link_const_type
1152 _S_maximum(_Link_const_type __X)
1154 return static_cast<_Link_const_type
>( _Node_base::_S_maximum(__X) );
1159 _M_new_node(const_reference __V,
1160 _Base_ptr
const __PARENT = NULL,
1161 _Base_ptr
const __LEFT = NULL,
1162 _Base_ptr
const __RIGHT = NULL)
1164 typename _Base::NoLeakAlloc noleak(
this);
1165 _Link_type new_node = noleak.get();
1166 this->_M_construct_node(new_node, __V, __PARENT, __LEFT, __RIGHT);
1167 noleak.disconnect();
1181 void _M_delete_node(_Link_type __p)
1183 this->_M_destroy_node(__p);
1184 this->_M_deallocate_node(__p);
1194 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS 1195 friend std::ostream&
1196 operator<<(std::ostream& o,
1199 o <<
"meta node: " << tree._M_header << std::endl;
1200 o <<
"root node: " << tree._M_root << std::endl;
1203 return o <<
"[empty " << __K <<
"d-tree " << &tree <<
"]";
1205 o <<
"nodes total: " << tree.size() << std::endl;
1206 o <<
"dimensions: " << __K << std::endl;
1209 typedef typename _Tree::_Link_type _Link_type;
1211 std::stack<_Link_const_type> s;
1212 s.push(tree._M_get_root());
1216 _Link_const_type n = s.top();
1218 o << *n << std::endl;
1219 if (_Tree::_S_left(n)) s.push(_Tree::_S_left(n));
1220 if (_Tree::_S_right(n)) s.push(_Tree::_S_right(n));
1232 #endif // include guard _Cmp value_comp() const
Comparator for the values in the KDTree.
Definition: kdtree.hpp:268
std::pair< const _Node< _Val > *, std::pair< size_t, typename _Dist::distance_type > > _S_node_nearest(const size_t __k, size_t __dim, SearchVal const &__val, const _Node< _Val > *__node, const _Node_base *__end, const _Node< _Val > *__best, typename _Dist::distance_type __max, const _Cmp &__cmp, const _Acc &__acc, const _Dist &__dist, _Predicate __p)
Definition: node.hpp:199
Definition: iterator.hpp:17
const _Dist & value_distance() const
Distance calculator between 2 value's element.
Definition: kdtree.hpp:287
Defines the interface of the _Region class.
Definition: kdtree.hpp:99
Defines the various functors and interfaces used for KDTree.
Definition: region.hpp:19
_Dist::distance_type _S_accumulate_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition: node.hpp:156
Definition: function.hpp:28
Defines the allocator interface as used by the KDTree class.
_Acc value_acc() const
Accessor to the value's elements.
Definition: kdtree.hpp:277
Definition: allocator.hpp:18
Defines interfaces for nodes as used by the KDTree class.
Definition: allocator.hpp:14
Defines interfaces for iterators as used by the KDTree class.