Spatial C++ Library
Generic Multi-Dimensional Containers and Spatial Operations
spatial_node.hpp
1 // -*- C++ -*-
2 //
3 // Copyright Sylvain Bougerel 2009 - 2013.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file COPYING or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
13 #ifndef SPATIAL_NODE_HPP
14 #define SPATIAL_NODE_HPP
15 
16 #include <iterator> // std::bidirectional_iterator_tag and
17  // std::forward_iterator_tag
18 #include "../spatial.hpp"
19 #include "spatial_assert.hpp"
20 #include "spatial_mutate.hpp"
21 
22 namespace spatial
23 {
24  namespace details
25  {
56  template <typename Link>
57  struct Node
58  {
61  typedef Link link_type;
62 
70 
79 
86  };
87 
95  template <typename Link>
96  inline bool header(const Node<Link>* x)
97  { return (x->left == x); }
98 
106  template <typename Link>
109  {
110  SPATIAL_ASSERT_CHECK(!header(x));
111  while (x->left != 0) x = x->left; return x;
112  }
113 
114  template <typename Link>
115  inline const Node<Link>* minimum(const Node<Link>* x)
116  {
117  SPATIAL_ASSERT_CHECK(!header(x));
118  while (x->left != 0) x = x->left; return x;
119  }
121 
129  template <typename Link>
132  {
133  SPATIAL_ASSERT_CHECK(!header(x));
134  while (x->right != 0) x = x->right; return x;
135  }
136 
137  template <typename Link>
138  inline const Node<Link>* maximum(const Node<Link>* x)
139  {
140  SPATIAL_ASSERT_CHECK(!header(x));
141  while (x->right != 0) x = x->right; return x;
142  }
144 
152  template <typename Link> Node<Link>*
154  increment(Node<Link>* x);
155 
156  template <typename Link>
157  inline const Node<Link>*
159  { return increment(const_cast<Node<Link>*>(x)); }
161 
170  template <typename Link>
172  Node<Link>*
173  decrement(Node<Link>* x);
174 
175  template <typename Link>
176  inline const Node<Link>*
178  { return decrement(const_cast<Node<Link>*>(x)); }
180 
189  template <typename Link> const Node<Link>*
190  preorder_increment(const Node<Link>* x);
191 
219  struct relaxed_invariant_tag { };
223 
227  template <typename Link>
228  inline typename Link::invariant_category
230  { return typename Link::invariant_category(); }
231 
241  template<typename Key, typename Value>
242  struct Kdtree_link : Node<Kdtree_link<Key, Value> >
243  {
245  typedef Key key_type;
247  typedef Value value_type;
252  typedef link_type* link_ptr;
254  typedef const link_type* const_link_ptr;
261 
263  Kdtree_link() : value() { }
264 
276  Value value;
277 
278  private:
288  };
289 
299  template<typename Key, typename Value>
300  struct Relaxed_kdtree_link : Node<Relaxed_kdtree_link<Key, Value> >
301  {
303  typedef Key key_type;
305  typedef Value value_type;
310  typedef link_type* link_ptr;
312  typedef const link_type* const_link_ptr;
319 
322 
334  Value value;
335 
339 
340  private:
350  };
351 
359  template <typename Key, typename Value>
363  {
364  return static_cast<Kdtree_link<Key, Value>*>(node);
365  }
366 
367  template <typename Key, typename Value>
368  inline const Kdtree_link<Key, Value>*
370  {
371  return static_cast<const Kdtree_link<Key, Value>*>(node);
372  }
374 
385  template <typename Value>
386  inline const typename Kdtree_link<Value, Value>::key_type&
388  {
389  return static_cast<const Kdtree_link<Value, Value>*>(node)->value;
390  }
391 
401  template <typename Key, typename Value>
402  inline const typename Kdtree_link<Key, Value>::key_type&
404  {
405  return static_cast<const Kdtree_link<Key, Value>*>(node)->value.first;
406  }
407 
415  template <typename Key, typename Value>
417  inline typename Kdtree_link<Key, Value>::value_type&
419  {
420  return static_cast<Kdtree_link<Key, Value>*>(node)->value;
421  }
422 
423  template <typename Key, typename Value>
424  inline const typename Kdtree_link<Key, Value>::value_type&
426  {
427  return static_cast<const Kdtree_link<Key, Value>*>(node)->value;
428  }
430 
438  template <typename Key, typename Value>
440  inline Relaxed_kdtree_link<Key, Value>*
442  {
443  return static_cast<Relaxed_kdtree_link<Key, Value>*>(node);
444  }
445 
446  template <typename Key, typename Value>
447  inline const Relaxed_kdtree_link<Key, Value>*
449  {
450  return static_cast<const Relaxed_kdtree_link<Key, Value>*>(node);
451  }
453 
464  template <typename Value>
465  inline const typename Relaxed_kdtree_link<Value, Value>::key_type&
467  {
468  return static_cast
470  }
471 
481  template <typename Key, typename Value>
482  inline const typename Relaxed_kdtree_link<Key, Value>::key_type&
484  {
485  return static_cast<const Relaxed_kdtree_link<Key, Value>*>
486  (node)->value.first;
487  }
488 
496  template <typename Key, typename Value>
498  inline typename Relaxed_kdtree_link<Key, Value>::value_type&
500  {
501  return static_cast<Relaxed_kdtree_link<Key, Value>*>(node)->value;
502  }
503 
504  template <typename Key, typename Value>
505  inline const typename Relaxed_kdtree_link<Key, Value>::value_type&
507  {
508  return static_cast<const Relaxed_kdtree_link<Key, Value>*>(node)->value;
509  }
511 
522  template <typename Link>
524  void swap_node_aux(Node<Link>* a, Node<Link>* b);
525 
526  template<typename Key, typename Value>
529  { swap_node_aux(a, b); std::swap(a, b); }
530 
531  template<typename Key, typename Value>
534  {
535  swap_node_aux(a, b);
536  std::swap(link(a)->weight, link(b)->weight);
537  std::swap(a, b);
538  }
540 
548  template<typename Link>
550  {
551  public:
553  typedef typename Link::value_type& reference;
554  typedef typename Link::value_type* pointer;
555  typedef std::ptrdiff_t difference_type;
556  typedef std::bidirectional_iterator_tag iterator_category;
557  typedef typename Link::node_ptr node_ptr;
558 
559  private:
561 
562  public:
565  Node_iterator() : node() { }
566 
568  explicit Node_iterator(node_ptr x) : node(x) { }
569 
571  reference operator*()
572  { return value(node); }
573 
575  pointer operator->()
576  { return &value(node); }
577 
579  Self& operator++()
580  { node = increment(node); return *this; }
581 
584  Self operator++(int)
585  { Self tmp = *this; node = increment(node); return tmp; }
586 
588  Self& operator--()
589  { node = decrement(node); return *this; }
590 
593  Self operator--(int)
594  { Self tmp = *this; node = decrement(node); return tmp; }
595 
597  bool operator==(const Self& x) const
598  { return node == x.node; }
599 
601  bool operator!=(const Self& x) const
602  { return node != x.node; }
603 
605  node_ptr node;
606  };
607 
615  template<typename Link>
617  {
618  public:
620  typedef const typename Link::value_type& reference;
621  typedef const typename Link::value_type* pointer;
622  typedef std::ptrdiff_t difference_type;
623  typedef std::bidirectional_iterator_tag iterator_category;
624  typedef typename Link::const_node_ptr node_ptr;
625 
626  private:
629 
630  public:
634 
636  explicit
637  Const_node_iterator(node_ptr x) : node(x) { }
638 
640  Const_node_iterator(const iterator& it) : node(it.node) { }
641 
643  reference operator*()
644  { return const_value(node); }
645 
647  pointer operator->()
648  { return &const_value(node); }
649 
651  Self& operator++()
652  { node = increment(node); return *this; }
653 
656  Self operator++(int)
657  { Self tmp = *this; node = increment(node); return tmp; }
658 
660  Self& operator--()
661  { node = decrement(node); return *this; }
662 
665  Self operator--(int)
666  { Self tmp = *this; node = decrement(node); return tmp; }
667 
669  bool operator==(const Self& x) const
670  { return node == x.node; }
671 
673  bool operator!=(const Self& x) const
674  { return node != x.node; }
675 
677  node_ptr node;
678  };
679 
687  template<typename Link>
689  {
691  typedef const typename Link::value_type& reference;
692  typedef const typename Link::value_type* pointer;
693  typedef std::ptrdiff_t difference_type;
694  typedef std::forward_iterator_tag iterator_category;
695  typedef typename Link::const_node_ptr node_ptr;
696 
697  private:
699 
700  public:
704 
706  explicit
707  Preorder_node_iterator(node_ptr x) : node(x) { }
708 
710  reference operator*()
711  { return const_value(node); }
712 
714  pointer operator->()
715  { return &const_value(node); }
716 
718  Self& operator++()
719  { node = preorder_increment(node); return *this; }
720 
723  Self operator++(int)
724  { Self tmp = *this; node = preorder_increment(node); return tmp; }
725 
727  bool operator==(const Self& x) const
728  { return node == x.node; }
729 
731  bool operator!=(const Self& x) const
732  { return node != x.node; }
733 
735  node_ptr node;
736  };
737 
738  template <typename Link> inline Node<Link>* increment(Node<Link>* x)
739  {
740  SPATIAL_ASSERT_CHECK(!header(x));
741  if (x->right != 0)
742  {
743  x = x->right;
744  while (x->left != 0) { x = x->left; }
745  }
746  else
747  {
748  Node<Link>* p = x->parent;
749  while (!header(p) && x == p->right)
750  { x = p; p = x->parent; }
751  x = p;
752  }
753  return x;
754  }
755 
756  template <typename Link> inline Node<Link>* decrement(Node<Link>* x)
757  {
758  SPATIAL_ASSERT_CHECK((!header(x) || x->parent != 0));
759  if (header(x))
760  { x = x->right; } // At header, 'right' points to the right-most node
761  else if (x->left != 0)
762  {
763  Node<Link>* y = x->left;
764  while (y->right != 0) { y = y->right; }
765  x = y;
766  }
767  else
768  {
769  Node<Link>* p = x->parent;
770  while (!header(p) && x == p->left)
771  { x = p; p = x->parent; }
772  x = p;
773  }
774  return x;
775  }
776 
777  template <typename Link>
778  inline void swap_node_aux
780  {
781  typedef Node<Link>* node_ptr;
782  if (a == b) return;
783  SPATIAL_ASSERT_CHECK(!header(a));
784  SPATIAL_ASSERT_CHECK(!header(b));
785  if (a->parent == b)
786  {
787  if (header(b->parent))
788  { b->parent->parent = a; }
789  else
790  {
791  if (b->parent->left == b) { b->parent->left = a; }
792  else { b->parent->right = a; }
793  }
794  if (a->left != 0) { a->left->parent = b; }
795  if (a->right != 0) { a->right->parent = b; }
796  a->parent = b->parent;
797  b->parent = a;
798  node_ptr a_left = a->left;
799  node_ptr a_right = a->right;
800  if (b->left == a)
801  {
802  if (b->right != 0) { b->right->parent = a; }
803  a->left = b;
804  a->right = b->right;
805  }
806  else
807  {
808  if (b->left != 0) { b->left->parent = a; }
809  a->left = b->left;
810  a->right = b;
811  }
812  b->left = a_left;
813  b->right = a_right;
814  }
815  else if (b->parent == a)
816  {
817  if (header(a->parent))
818  { a->parent->parent = b; }
819  else
820  {
821  if (a->parent->left == a) { a->parent->left = b; }
822  else { a->parent->right = b; }
823  }
824  if (b->left != 0) { b->left->parent = a; }
825  if (b->right != 0) { b->right->parent = a; }
826  b->parent = a->parent;
827  a->parent = b;
828  node_ptr b_left = b->left;
829  node_ptr b_right = b->right;
830  if (a->left == b)
831  {
832  if (a->right != 0) { a->right->parent = b; }
833  b->left = a;
834  b->right = a->right;
835  }
836  else
837  {
838  if (a->left != 0) { a->left->parent = b; }
839  b->left = a->left;
840  b->right = a;
841  }
842  a->left = b_left;
843  a->right = b_right;
844  }
845  else
846  {
847  if (header(a->parent))
848  { a->parent->parent = b; }
849  else
850  {
851  if (a->parent->left == a) { a->parent->left = b; }
852  else { a->parent->right = b; }
853  }
854  if (header(b->parent))
855  { b->parent->parent = a; }
856  else
857  {
858  if (b->parent->left == b) { b->parent->left = a; }
859  else { b->parent->right = a; }
860  }
861  if (a->left != 0) { a->left->parent = b; }
862  if (b->left != 0) { b->left->parent = a; }
863  if (a->right != 0) { a->right->parent = b; }
864  if (b->right != 0) { b->right->parent = a; }
865  std::swap(a->parent, b->parent);
866  std::swap(a->left, b->left);
867  std::swap(a->right, b->right);
868  }
869  }
870 
871  template <typename Link> inline const Node<Link>*
873  {
874  if (x->left != 0) { x = x->left; }
875  else if (x->right != 0) { x = x->right; }
876  else
877  {
878  const Node<Link>* p = x->parent;
879  while (!header(p) && (x == p->right || p->right == 0))
880  { x = p; p = x->parent; }
881  x = p;
882  if (!header(p)) { x = x->right; }
883  }
884  return x;
885  }
886 
887  } // namespace details
888 } // namespace spatial
889 
890 #endif // SPATIAL_NODE_HPP
Node_iterator(node_ptr x)
Build and assign an interator to a link pointer.
Self & operator++()
Moves the iterator to the next node in preorder transversal.
Self & operator++()
Moves the iterator to the next node in inorder transversal.
Preorder_node_iterator< Link > Self
A bidirectional iterator traversing all node in the tree in inorder traversal.
Node_iterator< Link > Self
A bidirectional iterator traversing all node in the tree in inorder traversal.
node_ptr node
The node pointed to by the iterator.
reference operator*()
Dereferance the iterator: return the value of the node.
Const_node_iterator< Link > Self
bool operator!=(const Self &x) const
Check if 2 iterators are different: pointing at different nodes.
Const_node_iterator(const iterator &it)
Convert an iterator into a constant iterator.
Self & operator++()
Moves the iterator to the next node in inorder transversal.
Link::invariant_category invariant_category(const Node< Link > *)
For a given node, this function returns the invariant category of the node.
const Link::value_type * pointer
Self operator++(int)
Moves the iterator to the next node in inorder transversal and returns the iterator value before the ...
mutate< typename Link::value_type >::type value_type
The basic node for any tree in the library.
Node_iterator()
Create an uninintialized iterator.
bool operator==(const Self &x) const
Check if 2 iterators are equal: pointing at the same node.
Node< Link > * maximum(Node< Link > *x)
Reach the left most node.
Node * left
A pointer to the left child node of the current node.
const Kdtree_link< Key, Value >::value_type & const_value(const Node< Kdtree_link< Key, Value > > *node)
This function converts a pointer on a node into a value for a Kdtree_link type.
std::bidirectional_iterator_tag iterator_category
const Kdtree_link< Value, Value >::key_type & const_key(const Node< Kdtree_link< Value, Value > > *node)
This function converts a pointer on a node into a key for a Kdtree_link type.
bool header(const Node< Link > *x)
Check if node is a header node.
Link link_type
The link type that indicate how to reach the key and/or the value from the node.
Node< Link > * minimum(Node< Link > *x)
Reach the left most node.
Const_node_iterator(node_ptr x)
Build and assign an interator to a link pointer.
Self & operator--()
Moves the iterator to the previous node in inorder transversal.
bool operator==(const Self &x) const
Check if 2 iterators are equal: pointing at the same node.
Preorder_node_iterator(node_ptr x)
Build and assign an interator to a link pointer.
node_ptr node
The node pointed to by the iterator.
Preorder_node_iterator()
Create an uninintialized iterator.
std::size_t weight_type
Defines weight as being a size.
Definition: spatial.hpp:76
reference operator*()
Dereferance the iterator: return the value of the node.
bool operator==(const Self &x) const
Check if 2 iterators are equal: pointing at the same node.
const Kdtree_link< Key, Value > * const_link(const Node< Kdtree_link< Key, Value > > *node)
This function converts a pointer on a node into a link for a Kdtree_link type.
Const_node_iterator()
Create an uninintialized iterator.
pointer operator->()
Dereferance the iterator: return the pointer to the value of the node.
Self operator++(int)
Moves the iterator to the next node in preorder transversal and returns the iterator value before the...
The category of invariants for a k-d tree node: strict or relaxed.
node_ptr node
The node pointed to by the iterator.
Self & operator--()
Moves the iterator to the previous node in inorder transversal.
Node< Link > * increment(Node< Link > *x)
Reach the next node in symetric transversal order.
Self operator--(int)
Moves the iterator to the previous node in inorder transversal and returns the iterator value before ...
The main namespace used in the library.
Definition: algorithm.hpp:23
const Link::value_type & reference
A forward iterator that iterates through the node of the container in preorder transversal.
void swap_node(Node< Kdtree_link< Key, Value > > *&a, Node< Kdtree_link< Key, Value > > *&b)
Swaps nodes position in the tree.
pointer operator->()
Dereferance the iterator: return the pointer to the value of the node.
Node * right
A pointer to the right child node of the current node.
reference operator*()
Dereferance the iterator: return the value of the node.
void swap_node_aux(Node< Link > *a, Node< Link > *b)
Swaps nodes position in the tree.
Kdtree_link< Key, Value > * link(Node< Kdtree_link< Key, Value > > *node)
This function converts a pointer on a node into a link for a Kdtree_link type.
mutate< typename Link::value_type >::type value_type
Kdtree_link< Key, Value >::value_type & value(Node< Kdtree_link< Key, Value > > *node)
This function converts a pointer on a node into a value for a Kdtree_link type.
std::forward_iterator_tag iterator_category
Self operator--(int)
Moves the iterator to the previous node in inorder transversal and returns the iterator value before ...
bool operator!=(const Self &x) const
Check if 2 iterators are different: pointing at different nodes.
mutate< typename Link::value_type >::type value_type
Node< Link > * decrement(Node< Link > *x)
Reach the previous node in symetric transversal order.
Node * parent
A pointer to the parent of the current node.
bool operator!=(const Self &x) const
Check if 2 iterators are different: pointing at different nodes.
Self operator++(int)
Moves the iterator to the next node in inorder transversal and returns the iterator value before the ...
pointer operator->()
Dereferance the iterator: return the pointer to the value of the node.
const Node< Link > * preorder_increment(const Node< Link > *x)
Reach the next node in preorder transversal.
std::bidirectional_iterator_tag iterator_category