source: CMT/HEAD/source/cmt_map.h @ 662

Last change on this file since 662 was 662, checked in by rybkin, 10 years ago

See C.L. 521

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