source: CMT/v1r14p20031120/src/cmt_map.h @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 6.6 KB
Line 
1#ifndef __cmt_map_h__
2#define __cmt_map_h__
3
4#include "cmt_std.h"
5#include "cmt_string.h"
6#include "cmt_vector.h"
7
8#include <stdlib.h>
9
10/**
11 *    class cmt_node
12 *
13 *   Implements a binary tree of T* keyed by the class K
14 *
15 *   The class K must have the < and > operators.
16 *
17 *   This is the basic constituent for the cmt_map class.
18 */
19template <class K, class T> class cmt_node
20{
21public:
22
23  /**
24   * Required constructor.
25   * Provides the key and the value.
26   */
27  cmt_node (const K& key, T& t) : 
28    m_left (0),
29    m_key (key),
30    m_t (&t),
31    m_right (0)
32  {
33  }
34
35  /**
36   *  Destructor
37   */
38  ~cmt_node ()
39  {
40    clear ();
41  }
42
43  /**
44   *   Recursive clear operation.
45   *   Will delete sub-nodes
46   */
47  void clear ()
48  {
49    if (m_left == 0) return;
50
51    delete m_left;
52    m_left = 0;
53
54    m_t = 0;
55
56    if (m_right == 0) return;
57
58    delete m_right;
59    m_right = 0;
60  }
61
62  /**
63   *  Add an item.
64   */
65  void add (const K& key, T& t)
66  {
67    if (key < m_key)
68      { 
69        if (m_left == 0)
70          {
71            m_left = new cmt_node (key, t);
72          }
73        else
74          {
75            m_left->add (key, t);
76          }
77      }
78    else if (key > m_key)
79      { 
80        if (m_right == 0)
81          {
82            m_right = new cmt_node (key, t);
83          }
84        else
85          {
86            m_right->add (key, t);
87          }
88      }
89    else
90      {
91        m_t = &t;
92      }
93  }
94
95  /**
96   *   Finds whether the tree starting from this node
97   *   contains this key
98   */
99  bool has (const K& key) const
100  {
101    if (key < m_key)
102      { 
103        if (m_left == 0) return (false);
104        else return (m_left->has (key));
105      }
106    else if (key > m_key)
107      { 
108        if (m_right == 0) return (false);
109        else return (m_right->has (key));
110      }
111    else
112      {
113        return (true);
114      }
115  }
116
117  /**
118   *   Finds in the tree starting from this node
119   *   the value associated with this key
120   *   Return 0 if not found
121   */
122  T* find (const K& key) const
123  {
124    if (key < m_key)
125      { 
126        if (m_left == 0) return (0);
127        else return (m_left->find (key));
128      }
129    else if (key > m_key)
130      { 
131        if (m_right == 0) return (0);
132        else return (m_right->find (key));
133      }
134    else
135      {
136        return (m_t);
137      }
138  }
139
140  /**
141   *   Finds in the tree starting from this node
142   *   the node holding the value associated with this key
143   *   Return 0 if not found
144   */
145  const cmt_node* find_node (const K& key) const
146  {
147    if (key < m_key)
148      { 
149        if (m_left == 0) return (0);
150        else return (m_left->find_node (key));
151      }
152    else if (key > m_key)
153      { 
154        if (m_right == 0) return (0);
155        else return (m_right->find_node (key));
156      }
157    else
158      {
159        return (this);
160      }
161  }
162
163protected:
164  cmt_node<K,T>* m_left;
165  K m_key;
166  T* m_t;
167  cmt_node<K,T>* m_right;
168};
169
170
171/**
172 *   Public interface for maps.
173 *   It is implemented by one top cmt_node.
174 *
175 *   At creation the map is empty.
176 */
177template <class K, class T> class cmt_map
178{
179public:
180
181  /**
182   *  Constructor
183   */
184  cmt_map () : m_top (0)
185  {
186  }
187
188  /**
189   *  Destructor
190   */
191  ~cmt_map ()
192  {
193    clear ();
194  }
195
196  /**
197   * clear: erase everything from this map
198   */
199  void clear ()
200  {
201    if (m_top == 0) return;
202
203    delete m_top;
204    m_top = 0;
205  }
206
207  /**
208   *  Add an entry.
209   *
210   *  Existing entries with the same key will be overridden
211   */
212  void add (const K& key, T& t)
213  {
214    if (m_top == 0)
215      {
216        m_top = new cmt_node<K, T> (key, t);
217      }
218    else
219      {
220        m_top->add (key, t);
221      }
222  }
223
224  void add (const K& key, T* t)
225  {
226    if (m_top == 0)
227      {
228        m_top = new cmt_node<K, T> (key, *t);
229      }
230    else
231      {
232        m_top->add (key, *t);
233      }
234  }
235
236  /**
237   *   Finds whether there is a node holding that key
238   */
239  bool has (const K& key) const
240  {
241    if (m_top == 0) return (false);
242
243    return (m_top->has (key));
244  }
245
246  /**
247   *   Finds the value associated with that key.
248   *   Returns 0 if not found
249   */
250  T* find (const K& key) const
251  {
252    if (m_top == 0) return (0);
253
254    return (m_top->find (key));
255  }
256
257  /**
258   *   Finds the node containing the value associated with that key.
259   *   Returns 0 if not found
260   */
261  const cmt_node<K, T>* find_node (const K& key) const
262  {
263    if (m_top == 0) return (0);
264
265    return (m_top->find_node (key));
266  }
267
268    /*
269  T& operator [] (const K& key)
270  {
271    T* t = find (key);
272   
273    if (t == 0)
274      {
275        static T t;
276       
277        add (key, t);
278        return ((*this)[key]);
279      }
280    else
281      {
282        return (*t);
283      }
284  }
285    */
286
287private:
288  cmt_node<K, T>* m_top;
289};
290
291
292
293
294
295/* ------------------------------------------------------------
296
297   This is a future possible implementation for the remove node function
298
299  void add (cmt_node* other)
300  {
301    if (other->m_key < m_key)
302      {
303        if (m_left == 0)
304          {
305            m_left = other;
306          }
307        else
308          {
309            m_left->add (other);
310          }
311      }
312    else if (other->m_key > m_key)
313      {
314        if (m_right == 0)
315          {
316            m_right = other;
317          }
318        else
319          {
320            m_right->add (other);
321          }
322      }
323    else
324      {
325        m_t = other->m_t;
326      }
327  }
328
329  cmt_node* remove_greatest ()
330  {
331    if (m_right == 0) return (this);
332
333    cmt_node* result = m_right->remove_greatest ();
334    if (result == m_right) m_right = 0;
335
336    return (result);
337  }
338
339  cmt_node* remove_node (const K& key)
340  {
341    if (key < m_key)
342      {
343        if (m_left != 0)
344          {
345            cmt_node* node = m_left->remove_node (key);
346            if (node != 0)
347              {
348                delete m_left;
349                m_left = node;
350              }
351          }
352
353        return (0);
354      }
355    else if (key > m_key)
356      {
357        if (m_right != 0)
358          {
359            cmt_node* node = m_right->remove_node (key);
360            if (node != 0)
361              {
362                delete m_right;
363                m_right = node;
364              }
365          }
366
367        return (0);
368      }
369    else
370      {
371        // This node will be removed.
372        // The replacement will be returned.
373
374        if (m_left == 0)
375          {
376            cmt_node* rep = m_right;
377            m_right == 0;
378            return (rep);
379          }
380        else if (m_right == 0)
381          {
382            cmt_node* rep = m_left;
383            m_left == 0;
384            return (rep);
385          }
386        else
387          {
388            // here both sides are busy
389
390            cmt_node* rep = remove_greatest ();
391
392            rep->add (this);
393
394            return (rep);
395          }
396
397        return (this);
398      }
399  }
400
401
402  void cmt_map::remove (const K& key)
403  {
404    if (m_top == 0) return;
405
406    cmt_node<K, T>* node = m_top->remove (key);
407    if (node == 0) return;
408
409    if (node == m_top)
410      {
411      }
412    else
413      {
414      }
415  }
416
417
418
419 ------------------------------------------------------------ */
420
421#endif
422
Note: See TracBrowser for help on using the repository browser.