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