libutil++  1.9.3
 All Classes Functions Variables
radix_tree_it.h
1 /*
2 ** libutil++
3 ** $Id: radix_tree_it.h 1653 2016-02-28 19:54:59Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 #ifndef __libutilxx__sella__container__radix_tree_it_H__
10 #define __libutilxx__sella__container__radix_tree_it_H__
11 
12 #include <iterator>
13 
14 namespace sella {
15  namespace container {
16  // forward declaration
17  template <typename K, typename T> class radix_tree;
18  template <typename K, typename T> class radix_tree_node;
19 
20  template <typename K, typename T>
21  class radix_tree_it : public std::iterator<std::forward_iterator_tag, std::pair<K, T> > {
22  friend class radix_tree<K, T>;
23 
24  public:
25  radix_tree_it() : m_pointee(0) { }
26  ~radix_tree_it() { }
27 
28  std::pair<const K, T>& operator* () const;
29  std::pair<const K, T>* operator-> () const;
30  const radix_tree_it<K, T>& operator++ ();
31  radix_tree_it<K, T> operator++ (int);
32  // const radix_tree_it<K, T>& operator-- ();
33  bool operator!= (const radix_tree_it<K, T> &lhs) const;
34  bool operator== (const radix_tree_it<K, T> &lhs) const;
35 
36  private:
37  radix_tree_node<K, T> *m_pointee;
38  radix_tree_it(radix_tree_node<K, T> *p) : m_pointee(p) { }
39 
40  radix_tree_node<K, T>* increment(radix_tree_node<K, T>* node) const;
41  radix_tree_node<K, T>* descend(radix_tree_node<K, T>* node) const;
42  };
43 
44  template <typename K, typename T>
46  {
47  radix_tree_node<K, T>* parent = node->m_parent;
48 
49  if (parent == NULL)
50  return NULL;
51 
52  typename radix_tree_node<K, T>::it_child it = parent->m_children.find(node->m_key);
53  assert(it != parent->m_children.end());
54  ++it;
55 
56  if (it == parent->m_children.end())
57  return increment(parent);
58  else
59  return descend(it->second);
60  }
61 
62  template <typename K, typename T>
63  radix_tree_node<K, T>* radix_tree_it<K, T>::descend(radix_tree_node<K, T>* node) const
64  {
65  if (node->m_is_leaf)
66  return node;
67 
68  typename radix_tree_node<K, T>::it_child it = node->m_children.begin();
69 
70  assert(it != node->m_children.end());
71 
72  return descend(it->second);
73  }
74 
75  template <typename K, typename T>
76  std::pair<const K, T>& radix_tree_it<K, T>::operator* () const
77  {
78  return *m_pointee->m_value;
79  }
80 
81  template <typename K, typename T>
82  std::pair<const K, T>* radix_tree_it<K, T>::operator-> () const
83  {
84  return m_pointee->m_value;
85  }
86 
87  template <typename K, typename T>
88  bool radix_tree_it<K, T>::operator!= (const radix_tree_it<K, T> &lhs) const
89  {
90  return m_pointee != lhs.m_pointee;
91  }
92 
93  template <typename K, typename T>
94  bool radix_tree_it<K, T>::operator== (const radix_tree_it<K, T> &lhs) const
95  {
96  return m_pointee == lhs.m_pointee;
97  }
98 
99  template <typename K, typename T>
100  const radix_tree_it<K, T>& radix_tree_it<K, T>::operator++ ()
101  {
102  if (m_pointee != NULL) // it is undefined behaviour to dereference iterator that is out of bounds...
103  m_pointee = increment(m_pointee);
104  return *this;
105  }
106 
107  template <typename K, typename T>
108  radix_tree_it<K, T> radix_tree_it<K, T>::operator++ (int)
109  {
110  radix_tree_it<K, T> copy(*this);
111  ++(*this);
112  return copy;
113  }
114  }
115 }
116 
117 /*
118 template <typename K, typename T>
119 const radix_tree_it<K, T>& radix_tree_it<K, T>::operator-- ()
120 {
121  assert(m_pointee != NULL);
122 
123  return *this;
124 }
125 */
126 
127 #endif
128 
129 /*
130 ** vim: noet ts=3 sw=3
131 */