• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- BinTree.h ----------------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef MCLD_ADT_BITREE_H
10 #define MCLD_ADT_BITREE_H
11 
12 #include <mcld/ADT/Uncopyable.h>
13 #include <mcld/ADT/TreeBase.h>
14 #include <mcld/ADT/TreeAllocator.h>
15 
16 #include <cstddef>
17 #include <iterator>
18 #include <memory>
19 #include <queue>
20 #include <stack>
21 
22 namespace mcld {
23 
24 template<class DataType>
25 class BinaryTree;
26 
27 class DFSIterator : public TreeIteratorBase
28 {
29 public:
DFSIterator()30   DFSIterator()
31   : TreeIteratorBase()
32   { }
33 
DFSIterator(NodeBase * X)34   DFSIterator(NodeBase *X)
35     : TreeIteratorBase(X) {
36     if (hasRightChild())
37       m_Stack.push(m_pNode->right);
38     if (hasLeftChild())
39       m_Stack.push(m_pNode->left);
40   }
41 
~DFSIterator()42   virtual ~DFSIterator()
43   { }
44 
advance()45   void advance() {
46     if (m_Stack.empty()) { // reach the end
47       m_pNode = m_pNode->right; // should be root
48       return;
49     }
50     m_pNode = m_Stack.top();
51     m_Stack.pop();
52     if (hasRightChild())
53       m_Stack.push(m_pNode->right);
54     if (hasLeftChild())
55       m_Stack.push(m_pNode->left);
56   }
57 
58 private:
59     std::stack<NodeBase *> m_Stack;
60 };
61 
62 class BFSIterator : public TreeIteratorBase
63 {
64 public:
BFSIterator()65   BFSIterator()
66   : TreeIteratorBase()
67   { }
68 
BFSIterator(NodeBase * X)69   BFSIterator(NodeBase *X)
70     : TreeIteratorBase(X) {
71     if (hasRightChild())
72       m_Queue.push(m_pNode->right);
73     if (hasLeftChild())
74       m_Queue.push(m_pNode->left);
75   }
76 
~BFSIterator()77   virtual ~BFSIterator()
78   { }
79 
advance()80   void advance() {
81     if (m_Queue.empty()) { // reach the end
82       m_pNode = m_pNode->right; // should be root
83       return;
84     }
85     m_pNode = m_Queue.front();
86     m_Queue.pop();
87     if (hasRightChild())
88       m_Queue.push(m_pNode->right);
89     if (hasLeftChild())
90       m_Queue.push(m_pNode->left);
91   }
92 
93 private:
94     std::queue<NodeBase *> m_Queue;
95 };
96 
97 template<class DataType, class Traits, class IteratorType>
98 class PolicyIteratorBase : public IteratorType
99 {
100 public:
101   typedef DataType                       value_type;
102   typedef Traits                         traits;
103   typedef typename traits::pointer       pointer;
104   typedef typename traits::reference     reference;
105 
106   typedef PolicyIteratorBase<value_type, Traits, IteratorType>          Self;
107   typedef Node<value_type>                                              node_type;
108   typedef typename traits::nonconst_traits                              nonconst_traits;
109   typedef PolicyIteratorBase<value_type, nonconst_traits, IteratorType> iterator;
110   typedef typename traits::const_traits                                 const_traits;
111   typedef PolicyIteratorBase<value_type, const_traits, IteratorType>    const_iterator;
112   typedef std::forward_iterator_tag                                     iterator_category;
113   typedef size_t                                                        size_type;
114   typedef ptrdiff_t                                                     difference_type;
115 
116 public:
PolicyIteratorBase()117   PolicyIteratorBase()
118     : IteratorType() {}
119 
PolicyIteratorBase(const iterator & X)120   PolicyIteratorBase(const iterator &X)
121     : IteratorType(X.m_pNode) {}
122 
PolicyIteratorBase(NodeBase * X)123   explicit PolicyIteratorBase(NodeBase* X)
124     : IteratorType(X) {}
125 
~PolicyIteratorBase()126   virtual ~PolicyIteratorBase() {}
127 
128   // -----  operators  ----- //
129   pointer operator*() const
130   { return static_cast<node_type*>(IteratorType::m_pNode)->data; }
131 
132   reference operator->() const
133   { return *static_cast<node_type*>(IteratorType::m_pNode)->data; }
134 
hasData()135   bool hasData() const
136   { return (!IteratorType::isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }
137 
138 };
139 
140 template<class DataType, class Traits, class IteratorType>
141 class PolicyIterator : public PolicyIteratorBase<DataType, Traits, IteratorType>
142 {
143 public:
144   typedef PolicyIterator<DataType, Traits, IteratorType> Self;
145   typedef PolicyIteratorBase<DataType, Traits, IteratorType> Base;
146   typedef PolicyIterator<DataType, typename Traits::nonconst_traits, IteratorType> iterator;
147   typedef PolicyIterator<DataType, typename Traits::const_traits, IteratorType>    const_iterator;
148 
149 public:
PolicyIterator()150   PolicyIterator()
151     : Base() {}
152 
PolicyIterator(const iterator & X)153   PolicyIterator(const iterator &X)
154     : Base(X.m_pNode) {}
155 
PolicyIterator(NodeBase * X)156   explicit PolicyIterator(NodeBase* X)
157     : Base(X) {}
158 
~PolicyIterator()159   virtual ~PolicyIterator() {}
160 
161   Self& operator++() {
162     IteratorType::advance();
163     return *this;
164   }
165 
166   Self operator++(int) {
167     Self tmp = *this;
168     IteratorType::advance();
169     return tmp;
170   }
171 };
172 
173 template<class DataType>
174 class BinaryTree;
175 
176 /** \class TreeIterator
177  *  \brief TreeIterator provides full functions of binary tree's iterator.
178  *
179  *  TreeIterator is designed to compatible with STL iterators.
180  *  TreeIterator is bi-directional. Incremental direction means to move
181  *  rightward, and decremental direction is leftward.
182  *
183  *  @see TreeIteratorBase
184  */
185 template<class DataType, class Traits>
186 struct TreeIterator : public TreeIteratorBase
187 {
188 public:
189   typedef DataType                       value_type;
190   typedef Traits                         traits;
191   typedef typename traits::pointer       pointer;
192   typedef typename traits::reference     reference;
193 
194   typedef TreeIterator<value_type, Traits>          Self;
195   typedef Node<value_type>                          node_type;
196 
197   typedef typename traits::nonconst_traits          nonconst_traits;
198   typedef TreeIterator<value_type, nonconst_traits> iterator;
199   typedef typename traits::const_traits             const_traits;
200   typedef TreeIterator<value_type, const_traits>    const_iterator;
201   typedef std::bidirectional_iterator_tag           iterator_category;
202   typedef size_t                                    size_type;
203   typedef ptrdiff_t                                 difference_type;
204 
205 public:
TreeIteratorTreeIterator206   TreeIterator()
207   : TreeIteratorBase() {}
208 
TreeIteratorTreeIterator209   TreeIterator(const iterator &X)
210     : TreeIteratorBase(X.m_pNode) {}
211 
~TreeIteratorTreeIterator212   ~TreeIterator() {}
213 
214   // -----  operators  ----- //
215   pointer operator*() const
216   { return static_cast<node_type*>(m_pNode)->data; }
217 
218   reference operator->() const
219   { return *static_cast<node_type*>(m_pNode)->data; }
220 
isRootTreeIterator221   bool isRoot() const
222   { return (m_pNode->right == m_pNode); }
223 
hasDataTreeIterator224   bool hasData() const
225   { return (!isRoot() && (0 != static_cast<node_type*>(m_pNode)->data)); }
226 
227   Self& operator++() {
228     this->move<TreeIteratorBase::Rightward>();
229     return *this;
230   }
231 
232   Self operator++(int) {
233     Self tmp = *this;
234     this->move<TreeIteratorBase::Rightward>();
235     return tmp;
236   }
237 
238   Self& operator--() {
239     this->move<TreeIteratorBase::Leftward>();
240     return *this;
241   }
242 
243   Self operator--(int) {
244     Self tmp = *this;
245     this->move<TreeIteratorBase::Leftward>();
246     return tmp;
247   }
248 
TreeIteratorTreeIterator249   explicit TreeIterator(NodeBase* X)
250     : TreeIteratorBase(X) {}
251 };
252 
253 /** \class BinaryTreeBase
254  *  \brief BinaryTreeBase gives root node and memory management.
255  *
256  *  The memory management of nodes in is hidden by BinaryTreeBase.
257  *  BinaryTreeBase also provides the basic functions for merging a tree and
258  *  inserton of a node.
259  *
260  *  @see BinaryTree
261  */
262 template<class DataType>
263 class BinaryTreeBase : private Uncopyable
264 {
265 public:
266   typedef Node<DataType> NodeType;
267 protected:
268   /// TreeImpl - TreeImpl records the root node and the number of nodes
269   //
270   //    +---> Root(end) <---+
271   //    |        |left      |
272   //    |      begin        |
273   //    |     /     \       |
274   //    |  Left     Right   |
275   //    +---/         \-----+
276   //
277   class TreeImpl : public NodeFactory<DataType>
278   {
279     typedef typename NodeFactory<DataType>::iterator       iterator;
280     typedef typename NodeFactory<DataType>::const_iterator const_iterator;
281 
282   public:
283     NodeBase node;
284 
285   public:
TreeImpl()286     TreeImpl()
287       : NodeFactory<DataType>() {
288       node.left = node.right = &node;
289     }
290 
~TreeImpl()291     ~TreeImpl()
292     { }
293 
294     /// summon - change the final edges of pClient to our root
summon(TreeImpl & pClient)295     void summon(TreeImpl& pClient) {
296       if (this == &pClient)
297         return;
298 
299       iterator data;
300       iterator dEnd = pClient.end();
301       for (data = pClient.begin(); data!=dEnd; ++data ) {
302         if ((*data).left == &pClient.node)
303           (*data).left = &node;
304         if ((*data).right == &pClient.node)
305           (*data).right = &node;
306       }
307     }
308   }; // TreeImpl
309 
310 protected:
311   /// m_Root is a special object who responses:
312   //  - the pointer of root
313   //  - the simple factory of nodes.
314   TreeImpl m_Root;
315 
316 protected:
createNode()317   NodeType *createNode() {
318     NodeType *result = m_Root.produce();
319     result->left = result->right = &m_Root.node;
320     return result;
321   }
322 
destroyNode(NodeType * pNode)323   void destroyNode(NodeType *pNode) {
324     pNode->left = pNode->right = 0;
325     pNode->data = 0;
326     m_Root.deallocate(pNode);
327   }
328 
329 public:
BinaryTreeBase()330   BinaryTreeBase()
331   : m_Root()
332   { }
333 
~BinaryTreeBase()334   virtual ~BinaryTreeBase()
335   { }
336 
size()337   size_t size() const {
338     return m_Root.size();
339   }
340 
empty()341   bool empty() const {
342     return m_Root.empty();
343   }
344 
345 protected:
clear()346   void clear() {
347     m_Root.clear();
348   }
349 };
350 
351 /** \class BinaryTree
352  *  \brief An abstract data type of binary tree.
353  *
354  *  @see mcld::InputTree
355  */
356 template<class DataType>
357 class BinaryTree : public BinaryTreeBase<DataType>
358 {
359 public:
360   typedef size_t             size_type;
361   typedef ptrdiff_t          difference_type;
362   typedef DataType           value_type;
363   typedef value_type*        pointer;
364   typedef value_type&        reference;
365   typedef const value_type*  const_pointer;
366   typedef const value_type&  const_reference;
367 
368   typedef BinaryTree<DataType>  Self;
369   typedef TreeIterator<value_type, NonConstTraits<value_type> > iterator;
370   typedef TreeIterator<value_type, ConstTraits<value_type> >    const_iterator;
371 
372   typedef PolicyIterator<value_type, NonConstTraits<value_type>, DFSIterator> dfs_iterator;
373   typedef PolicyIterator<value_type, ConstTraits<value_type>, DFSIterator>    const_dfs_iterator;
374   typedef PolicyIterator<value_type, NonConstTraits<value_type>, BFSIterator> bfs_iterator;
375   typedef PolicyIterator<value_type, ConstTraits<value_type>, BFSIterator>    const_bfs_iterator;
376 
377 protected:
378   typedef Node<value_type> node_type;
379 
380 public:
381   // -----  constructors and destructor  ----- //
BinaryTree()382   BinaryTree()
383   : BinaryTreeBase<DataType>()
384   { }
385 
~BinaryTree()386   ~BinaryTree() {
387   }
388 
389   // -----  iterators  ----- //
bfs_begin()390   bfs_iterator bfs_begin()
391   { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
392 
bfs_end()393   bfs_iterator bfs_end()
394   { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
395 
bfs_begin()396   const_bfs_iterator bfs_begin() const
397   { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
398 
bfs_end()399   const_bfs_iterator bfs_end() const
400   { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
401 
dfs_begin()402   dfs_iterator dfs_begin()
403   { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
404 
dfs_end()405   dfs_iterator dfs_end()
406   { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
407 
dfs_begin()408   const_dfs_iterator dfs_begin() const
409   { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
410 
dfs_end()411   const_dfs_iterator dfs_end() const
412   { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
413 
root()414   iterator root()
415   { return iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
416 
root()417   const_iterator root() const
418   { return const_iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
419 
begin()420   iterator begin()
421   { return iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
422 
end()423   iterator end()
424   { return iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
425 
begin()426   const_iterator begin() const
427   { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
428 
end()429   const_iterator end() const
430   { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
431 
432   // ----- modifiers  ----- //
433   /// join - create a leaf node and merge it in the tree.
434   //  This version of join determines the direction on compilation time.
435   //  @param DIRECT the direction of the connecting edge of the parent node.
436   //  @param position the parent node
437   //  @param value the value being pushed.
438   template<size_t DIRECT>
join(TreeIteratorBase & pPosition,const DataType & pValue)439   BinaryTree& join(TreeIteratorBase& pPosition, const DataType& pValue) {
440     node_type *node = BinaryTreeBase<DataType>::createNode();
441     node->data = const_cast<DataType*>(&pValue);
442 
443     if (pPosition.isRoot())
444       pPosition.hook<TreeIteratorBase::Leftward>(node);
445     else
446       pPosition.hook<DIRECT>(node);
447 
448     return *this;
449   }
450 
451   /// merge - merge the tree
452   //  @param DIRECT the direction of the connecting edge of the parent node.
453   //  @param position the parent node
454   //  @param the tree being joined.
455   //  @return the joined tree
456   template<size_t DIRECT>
merge(TreeIteratorBase & pPosition,BinaryTree & pTree)457   BinaryTree& merge(TreeIteratorBase& pPosition, BinaryTree& pTree) {
458     if (this == &pTree)
459       return *this;
460 
461     if (!pTree.empty()) {
462       pPosition.hook<DIRECT>(pTree.m_Root.node.left);
463       BinaryTreeBase<DataType>::m_Root.summon(
464                                    pTree.BinaryTreeBase<DataType>::m_Root);
465       BinaryTreeBase<DataType>::m_Root.delegate(pTree.m_Root);
466       pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
467     }
468     return *this;
469   }
470 };
471 
472 } // namespace of mcld
473 
474 #endif
475 
476