source: CMT/v1r18p20041201/source/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: 10.8 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
177template <class K, class T> class cmt_vnode
178{
179public:
180
181  /**
182   * Required constructor.
183   * Provides the key and the value.
184   */
185  cmt_vnode (const K& key, T& t) : 
186    m_left (0),
187    m_key (key),
188    m_t (t),
189    m_right (0)
190  {
191  }
192
193  /**
194   *  Destructor
195   */
196  ~cmt_vnode ()
197  {
198    clear ();
199  }
200
201  /**
202   *   Recursive clear operation.
203   *   Will delete sub-nodes
204   */
205  void clear ()
206  {
207    if (m_left == 0) return;
208
209    delete m_left;
210    m_left = 0;
211
212    if (m_right == 0) return;
213
214    delete m_right;
215    m_right = 0;
216  }
217
218  /**
219   *  Add an item.
220   */
221  void add (const K& key, T& t)
222  {
223    if (key < m_key)
224      { 
225        if (m_left == 0)
226          {
227            m_left = new cmt_vnode (key, t);
228          }
229        else
230          {
231            m_left->add (key, t);
232          }
233      }
234    else if (key > m_key)
235      { 
236        if (m_right == 0)
237          {
238            m_right = new cmt_vnode (key, t);
239          }
240        else
241          {
242            m_right->add (key, t);
243          }
244      }
245    else
246      {
247        m_t = t;
248      }
249  }
250
251  /**
252   *   Finds whether the tree starting from this node
253   *   contains this key
254   */
255  bool has (const K& key) const
256  {
257    if (key < m_key)
258      { 
259        if (m_left == 0) return (false);
260        else return (m_left->has (key));
261      }
262    else if (key > m_key)
263      { 
264        if (m_right == 0) return (false);
265        else return (m_right->has (key));
266      }
267    else
268      {
269        return (true);
270      }
271  }
272
273  /**
274   *   Finds in the tree starting from this node
275   *   the value associated with this key
276   *   Return 0 if not found
277   */
278  const T* find (const K& key) const
279  {
280    if (key < m_key)
281      { 
282        if (m_left == 0) return (0);
283        else return (m_left->find (key));
284      }
285    else if (key > m_key)
286      { 
287        if (m_right == 0) return (0);
288        else return (m_right->find (key));
289      }
290    else
291      {
292        return (&m_t);
293      }
294  }
295
296  /**
297   *   Finds in the tree starting from this node
298   *   the node holding the value associated with this key
299   *   Return 0 if not found
300   */
301  const cmt_vnode* find_node (const K& key) const
302  {
303    if (key < m_key)
304      { 
305        if (m_left == 0) return (0);
306        else return (m_left->find_node (key));
307      }
308    else if (key > m_key)
309      { 
310        if (m_right == 0) return (0);
311        else return (m_right->find_node (key));
312      }
313    else
314      {
315        return (this);
316      }
317  }
318
319protected:
320  cmt_vnode<K,T>* m_left;
321  K m_key;
322  T m_t;
323  cmt_vnode<K,T>* m_right;
324};
325
326
327/**
328 *   Public interface for maps.
329 *   It is implemented by one top cmt_node.
330 *
331 *   At creation the map is empty.
332 */
333template <class K, class T> class cmt_map
334{
335public:
336
337  /**
338   *  Constructor
339   */
340  cmt_map () : m_top (0)
341  {
342  }
343
344  /**
345   *  Destructor
346   */
347  ~cmt_map ()
348  {
349    clear ();
350  }
351
352  /**
353   * clear: erase everything from this map
354   */
355  void clear ()
356  {
357    if (m_top != 0)
358      {
359        delete m_top;
360        m_top = 0;
361      }
362  }
363
364  /**
365   *  Add an entry.
366   *
367   *  Existing entries with the same key will be overridden
368   */
369  void add (const K& key, T& t)
370  {
371    if (m_top == 0)
372      {
373        m_top = new cmt_node<K, T> (key, t);
374      }
375    else
376      {
377        m_top->add (key, t);
378      }
379  }
380
381  void add (const K& key, T* t)
382  {
383    if (m_top == 0)
384      {
385        m_top = new cmt_node<K, T> (key, *t);
386      }
387    else
388      {
389        m_top->add (key, *t);
390      }
391  }
392
393  /**
394   *   Finds whether there is a node holding that key
395   */
396  bool has (const K& key) const
397  {
398    if (m_top != 0)
399      {
400        return (m_top->has (key));
401      }
402    else
403      {
404        return (false);
405      }
406  }
407
408  /**
409   *   Finds the value associated with that key.
410   *   Returns 0 if not found
411   */
412  T* find (const K& key) const
413  {
414    if (m_top != 0)
415      {
416        return (m_top->find (key));
417      }
418    else
419      {
420        return (0);
421      }
422  }
423
424  /**
425   *   Finds the node containing the value associated with that key.
426   *   Returns 0 if not found
427   */
428  const cmt_node<K, T>* find_node (const K& key) const
429  {
430    if (m_top == 0) return (0);
431
432    return (m_top->find_node (key));
433  }
434
435private:
436  cmt_node<K, T>* m_top;
437};
438
439template <class K, class T> class cmt_vmap
440{
441public:
442
443  /**
444   *  Constructor
445   */
446  cmt_vmap () : m_top (0)
447  {
448  }
449
450  /**
451   *  Destructor
452   */
453  ~cmt_vmap ()
454  {
455    clear ();
456  }
457
458  /**
459   * clear: erase everything from this map
460   */
461  void clear ()
462  {
463    if (m_top != 0)
464      {
465        delete m_top;
466        m_top = 0;
467      }
468  }
469
470  /**
471   *  Add an entry.
472   *
473   *  Existing entries with the same key will be overridden
474   */
475  void add (const K& key, T& t)
476  {
477    if (m_top == 0)
478      {
479        m_top = new cmt_vnode<K, T> (key, t);
480      }
481    else
482      {
483        m_top->add (key, t);
484      }
485  }
486
487  /**
488   *   Finds whether there is a node holding that key
489   */
490  bool has (const K& key) const
491  {
492    if (m_top != 0)
493      {
494        return (m_top->has (key));
495      }
496    else
497      {
498        return (false);
499      }
500  }
501
502  /**
503   *   Finds the value associated with that key.
504   *   Returns 0 if not found
505   */
506  const T* find (const K& key) const
507  {
508    if (m_top != 0)
509      {
510        return (m_top->find (key));
511      }
512    else
513      {
514        return (0);
515      }
516  }
517
518  /**
519   *   Finds the node containing the value associated with that key.
520   *   Returns 0 if not found
521   */
522  const cmt_vnode<K, T>* find_node (const K& key) const
523  {
524    if (m_top == 0) return (0);
525
526    return (m_top->find_node (key));
527  }
528
529private:
530  cmt_vnode<K, T>* m_top;
531};
532
533
534
535
536    /*
537  T& operator [] (const K& key)
538  {
539    T* t = find (key);
540   
541    if (t == 0)
542      {
543        static T t;
544       
545        add (key, t);
546        return ((*this)[key]);
547      }
548    else
549      {
550        return (*t);
551      }
552  }
553    */
554
555
556/* ------------------------------------------------------------
557
558   This is a future possible implementation for the remove node function
559
560  void add (cmt_node* other)
561  {
562    if (other->m_key < m_key)
563      {
564        if (m_left == 0)
565          {
566            m_left = other;
567          }
568        else
569          {
570            m_left->add (other);
571          }
572      }
573    else if (other->m_key > m_key)
574      {
575        if (m_right == 0)
576          {
577            m_right = other;
578          }
579        else
580          {
581            m_right->add (other);
582          }
583      }
584    else
585      {
586        m_t = other->m_t;
587      }
588  }
589
590  cmt_node* remove_greatest ()
591  {
592    if (m_right == 0) return (this);
593
594    cmt_node* result = m_right->remove_greatest ();
595    if (result == m_right) m_right = 0;
596
597    return (result);
598  }
599
600  cmt_node* remove_node (const K& key)
601  {
602    if (key < m_key)
603      {
604        if (m_left != 0)
605          {
606            cmt_node* node = m_left->remove_node (key);
607            if (node != 0)
608              {
609                delete m_left;
610                m_left = node;
611              }
612          }
613
614        return (0);
615      }
616    else if (key > m_key)
617      {
618        if (m_right != 0)
619          {
620            cmt_node* node = m_right->remove_node (key);
621            if (node != 0)
622              {
623                delete m_right;
624                m_right = node;
625              }
626          }
627
628        return (0);
629      }
630    else
631      {
632        // This node will be removed.
633        // The replacement will be returned.
634
635        if (m_left == 0)
636          {
637            cmt_node* rep = m_right;
638            m_right == 0;
639            return (rep);
640          }
641        else if (m_right == 0)
642          {
643            cmt_node* rep = m_left;
644            m_left == 0;
645            return (rep);
646          }
647        else
648          {
649            // here both sides are busy
650
651            cmt_node* rep = remove_greatest ();
652
653            rep->add (this);
654
655            return (rep);
656          }
657
658        return (this);
659      }
660  }
661
662
663  void cmt_map::remove (const K& key)
664  {
665    if (m_top == 0) return;
666
667    cmt_node<K, T>* node = m_top->remove (key);
668    if (node == 0) return;
669
670    if (node == m_top)
671      {
672      }
673    else
674      {
675      }
676  }
677
678
679
680 ------------------------------------------------------------ */
681
682#endif
683
Note: See TracBrowser for help on using the repository browser.