source: CMT/v1r25-branch/source/cmt_map.h

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

merge -r 646:663 HEAD

  • 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// Modified by Grigory Rybkin
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#ifndef __cmt_map_h__
9#define __cmt_map_h__
10
11#include "cmt_std.h"
12#include "cmt_string.h"
13#include "cmt_vector.h"
14
15#include <stdlib.h>
16
17/**
18 *    class cmt_node
19 *
20 *   Implements a binary tree of T* keyed by the class K
21 *
22 *   The class K must have the < and > operators.
23 *
24 *   This is the basic constituent for the cmt_map class.
25 */
26template <class K, class T> class cmt_node
27{
28public:
29
30  /**
31   * Required constructor.
32   * Provides the key and the value.
33   */
34  cmt_node (const K& key, T& t) : 
35    m_left (0),
36    m_key (key),
37    m_t (&t),
38    m_right (0)
39  {
40  }
41
42  /**
43   *  Destructor
44   */
45  ~cmt_node ()
46  {
47    clear ();
48  }
49
50  /**
51   *   Recursive clear operation.
52   *   Will delete sub-nodes
53   */
54  void clear ()
55  {
56    if (m_left == 0) return;
57
58    delete m_left;
59    m_left = 0;
60
61    m_t = 0;
62
63    if (m_right == 0) return;
64
65    delete m_right;
66    m_right = 0;
67  }
68
69  /**
70   *  Add an item.
71   */
72  void add (const K& key, T& t)
73  {
74    if (key < m_key)
75      { 
76        if (m_left == 0)
77          {
78            m_left = new cmt_node (key, t);
79          }
80        else
81          {
82            m_left->add (key, t);
83          }
84      }
85    else if (key > m_key)
86      { 
87        if (m_right == 0)
88          {
89            m_right = new cmt_node (key, t);
90          }
91        else
92          {
93            m_right->add (key, t);
94          }
95      }
96    else
97      {
98        m_t = &t;
99      }
100  }
101
102  /**
103   *   Finds whether the tree starting from this node
104   *   contains this key
105   */
106  bool has (const K& key) const
107  {
108    if (key < m_key)
109      { 
110        if (m_left == 0) return (false);
111        else return (m_left->has (key));
112      }
113    else if (key > m_key)
114      { 
115        if (m_right == 0) return (false);
116        else return (m_right->has (key));
117      }
118    else
119      {
120        return (true);
121      }
122  }
123
124  /**
125   *   Finds in the tree starting from this node
126   *   the value associated with this key
127   *   Return 0 if not found
128   */
129  T* find (const K& key) const
130  {
131    if (key < m_key)
132      { 
133        if (m_left == 0) return (0);
134        else return (m_left->find (key));
135      }
136    else if (key > m_key)
137      { 
138        if (m_right == 0) return (0);
139        else return (m_right->find (key));
140      }
141    else
142      {
143        return (m_t);
144      }
145  }
146
147  /**
148   *   Finds in the tree starting from this node
149   *   the node holding the value associated with this key
150   *   Return 0 if not found
151   */
152  const cmt_node* find_node (const K& key) const
153  {
154    if (key < m_key)
155      { 
156        if (m_left == 0) return (0);
157        else return (m_left->find_node (key));
158      }
159    else if (key > m_key)
160      { 
161        if (m_right == 0) return (0);
162        else return (m_right->find_node (key));
163      }
164    else
165      {
166        return (this);
167      }
168  }
169
170protected:
171  cmt_node<K,T>* m_left;
172  K m_key;
173  T* m_t;
174  cmt_node<K,T>* m_right;
175};
176
177
178template <class K, class T> class cmt_vnode
179{
180public:
181
182  /**
183   * Required constructor.
184   * Provides the key and the value.
185   */
186  cmt_vnode (const K& key, T& t) : 
187    m_left (0),
188    m_key (key),
189    m_t (t),
190    m_right (0)
191  {
192  }
193
194  /**
195   *  Destructor
196   */
197  ~cmt_vnode ()
198  {
199    clear ();
200  }
201
202  /**
203   *   Recursive clear operation.
204   *   Will delete sub-nodes
205   */
206  void clear ()
207  {
208    if (m_left == 0) return;
209
210    delete m_left;
211    m_left = 0;
212
213    if (m_right == 0) return;
214
215    delete m_right;
216    m_right = 0;
217  }
218
219  /**
220   *  Add an item.
221   */
222  void add (const K& key, T& t)
223  {
224    if (key < m_key)
225      { 
226        if (m_left == 0)
227          {
228            m_left = new cmt_vnode (key, t);
229          }
230        else
231          {
232            m_left->add (key, t);
233          }
234      }
235    else if (key > m_key)
236      { 
237        if (m_right == 0)
238          {
239            m_right = new cmt_vnode (key, t);
240          }
241        else
242          {
243            m_right->add (key, t);
244          }
245      }
246    else
247      {
248        m_t = t;
249      }
250  }
251
252  /**
253   *   Finds whether the tree starting from this node
254   *   contains this key
255   */
256  bool has (const K& key) const
257  {
258    if (key < m_key)
259      { 
260        if (m_left == 0) return (false);
261        else return (m_left->has (key));
262      }
263    else if (key > m_key)
264      { 
265        if (m_right == 0) return (false);
266        else return (m_right->has (key));
267      }
268    else
269      {
270        return (true);
271      }
272  }
273
274  /**
275   *   Finds in the tree starting from this node
276   *   the value associated with this key
277   *   Return 0 if not found
278   */
279  T* find (const K& key)
280    //  const T* find (const K& key) const
281  {
282    if (key < m_key)
283      { 
284        if (m_left == 0) return (0);
285        else return (m_left->find (key));
286      }
287    else if (key > m_key)
288      { 
289        if (m_right == 0) return (0);
290        else return (m_right->find (key));
291      }
292    else
293      {
294        return (&m_t);
295      }
296  }
297
298  /**
299   *   Finds in the tree starting from this node
300   *   the node holding the value associated with this key
301   *   Return 0 if not found
302   */
303  const cmt_vnode* find_node (const K& key) const
304  {
305    if (key < m_key)
306      { 
307        if (m_left == 0) return (0);
308        else return (m_left->find_node (key));
309      }
310    else if (key > m_key)
311      { 
312        if (m_right == 0) return (0);
313        else return (m_right->find_node (key));
314      }
315    else
316      {
317        return (this);
318      }
319  }
320
321protected:
322  cmt_vnode<K,T>* m_left;
323  K m_key;
324  T m_t;
325  cmt_vnode<K,T>* m_right;
326};
327
328
329/**
330 *   Public interface for maps.
331 *   It is implemented by one top cmt_node.
332 *
333 *   At creation the map is empty.
334 */
335template <class K, class T> class cmt_map
336{
337public:
338
339  /**
340   *  Constructor
341   */
342  cmt_map () : m_top (0)
343  {
344  }
345
346  /**
347   *  Destructor
348   */
349  ~cmt_map ()
350  {
351    clear ();
352  }
353
354  /**
355   * clear: erase everything from this map
356   */
357  void clear ()
358  {
359    if (m_top != 0)
360      {
361        delete m_top;
362        m_top = 0;
363      }
364  }
365
366  /**
367   *  Add an entry.
368   *
369   *  Existing entries with the same key will be overridden
370   */
371  void add (const K& key, T& t)
372  {
373    if (m_top == 0)
374      {
375        m_top = new cmt_node<K, T> (key, t);
376      }
377    else
378      {
379        m_top->add (key, t);
380      }
381  }
382
383  void add (const K& key, T* t)
384  {
385    if (m_top == 0)
386      {
387        m_top = new cmt_node<K, T> (key, *t);
388      }
389    else
390      {
391        m_top->add (key, *t);
392      }
393  }
394
395  /**
396   *   Finds whether there is a node holding that key
397   */
398  bool has (const K& key) const
399  {
400    if (m_top != 0)
401      {
402        return (m_top->has (key));
403      }
404    else
405      {
406        return (false);
407      }
408  }
409
410  /**
411   *   Finds the value associated with that key.
412   *   Returns 0 if not found
413   */
414  T* find (const K& key) const
415  {
416    if (m_top != 0)
417      {
418        return (m_top->find (key));
419      }
420    else
421      {
422        return (0);
423      }
424  }
425
426  /**
427   *   Finds the node containing the value associated with that key.
428   *   Returns 0 if not found
429   */
430  const cmt_node<K, T>* find_node (const K& key) const
431  {
432    if (m_top == 0) return (0);
433
434    return (m_top->find_node (key));
435  }
436
437private:
438  cmt_node<K, T>* m_top;
439};
440
441template <class K, class T> class cmt_vmap
442{
443public:
444
445  /**
446   *  Constructor
447   */
448  cmt_vmap () : m_top (0)
449  {
450  }
451
452  /**
453   *  Destructor
454   */
455  ~cmt_vmap ()
456  {
457    clear ();
458  }
459
460  /**
461   * clear: erase everything from this map
462   */
463  void clear ()
464  {
465    if (m_top != 0)
466      {
467        delete m_top;
468        m_top = 0;
469      }
470  }
471
472  /**
473   *  Add an entry.
474   *
475   *  Existing entries with the same key will be overridden
476   */
477  void add (const K& key, T& t)
478  {
479    if (m_top == 0)
480      {
481        m_top = new cmt_vnode<K, T> (key, t);
482      }
483    else
484      {
485        m_top->add (key, t);
486      }
487  }
488
489  /**
490   *   Finds whether there is a node holding that key
491   */
492  bool has (const K& key) const
493  {
494    if (m_top != 0)
495      {
496        return (m_top->has (key));
497      }
498    else
499      {
500        return (false);
501      }
502  }
503
504  /**
505   *   Finds the value associated with that key.
506   *   Returns 0 if not found
507   */
508  T* find (const K& key) const
509    //  const T* find (const K& key) const
510  {
511    if (m_top != 0)
512      {
513        return (m_top->find (key));
514      }
515    else
516      {
517        return (0);
518      }
519  }
520
521  /**
522   *   Finds the node containing the value associated with that key.
523   *   Returns 0 if not found
524   */
525  const cmt_vnode<K, T>* find_node (const K& key) const
526  {
527    if (m_top == 0) return (0);
528
529    return (m_top->find_node (key));
530  }
531
532private:
533  cmt_vnode<K, T>* m_top;
534};
535
536
537
538
539    /*
540  T& operator [] (const K& key)
541  {
542    T* t = find (key);
543   
544    if (t == 0)
545      {
546        static T t;
547       
548        add (key, t);
549        return ((*this)[key]);
550      }
551    else
552      {
553        return (*t);
554      }
555  }
556    */
557
558
559/* ------------------------------------------------------------
560
561   This is a future possible implementation for the remove node function
562
563  void add (cmt_node* other)
564  {
565    if (other->m_key < m_key)
566      {
567        if (m_left == 0)
568          {
569            m_left = other;
570          }
571        else
572          {
573            m_left->add (other);
574          }
575      }
576    else if (other->m_key > m_key)
577      {
578        if (m_right == 0)
579          {
580            m_right = other;
581          }
582        else
583          {
584            m_right->add (other);
585          }
586      }
587    else
588      {
589        m_t = other->m_t;
590      }
591  }
592
593  cmt_node* remove_greatest ()
594  {
595    if (m_right == 0) return (this);
596
597    cmt_node* result = m_right->remove_greatest ();
598    if (result == m_right) m_right = 0;
599
600    return (result);
601  }
602
603  cmt_node* remove_node (const K& key)
604  {
605    if (key < m_key)
606      {
607        if (m_left != 0)
608          {
609            cmt_node* node = m_left->remove_node (key);
610            if (node != 0)
611              {
612                delete m_left;
613                m_left = node;
614              }
615          }
616
617        return (0);
618      }
619    else if (key > m_key)
620      {
621        if (m_right != 0)
622          {
623            cmt_node* node = m_right->remove_node (key);
624            if (node != 0)
625              {
626                delete m_right;
627                m_right = node;
628              }
629          }
630
631        return (0);
632      }
633    else
634      {
635        // This node will be removed.
636        // The replacement will be returned.
637
638        if (m_left == 0)
639          {
640            cmt_node* rep = m_right;
641            m_right == 0;
642            return (rep);
643          }
644        else if (m_right == 0)
645          {
646            cmt_node* rep = m_left;
647            m_left == 0;
648            return (rep);
649          }
650        else
651          {
652            // here both sides are busy
653
654            cmt_node* rep = remove_greatest ();
655
656            rep->add (this);
657
658            return (rep);
659          }
660
661        return (this);
662      }
663  }
664
665
666  void cmt_map::remove (const K& key)
667  {
668    if (m_top == 0) return;
669
670    cmt_node<K, T>* node = m_top->remove (key);
671    if (node == 0) return;
672
673    if (node == m_top)
674      {
675      }
676    else
677      {
678      }
679  }
680
681
682
683 ------------------------------------------------------------ */
684
685#endif
686
Note: See TracBrowser for help on using the repository browser.