Back to index

texmacs  1.0.7.15
rel_hashmap.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : rel_hashmap.cpp
00004 * DESCRIPTION: Relative hashmaps are lists of hashmaps
00005 *              the value of an entry is the value relative to
00006 *              the last hashmap in the list for which the value is defined.
00007 *              Relative hashmaps can be used to perform small local
00008 *              changes on a hashmap, which may be discarded or
00009 *              confirmed afterwards.
00010 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00011 *******************************************************************************
00012 * This software falls under the GNU general public license version 3 or later.
00013 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00014 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00015 ******************************************************************************/
00016 
00017 #ifndef REL_HASHMAP_CC
00018 #define REL_HASHMAP_CC
00019 #include "rel_hashmap.hpp"
00020 
00021 template <class T, class U> U
00022 rel_hashmap<T,U>::operator [] (T x) {
00023   ASSERT (rep != NULL, "invalid relative hashmap");
00024   if (rep->item->contains (x) || is_nil (rep->next)) return rep->item [x];
00025   return rep->next [x];
00026 }
00027 
00028 template <class T, class U> U&
00029 rel_hashmap<T,U>::operator () (T x) {
00030   ASSERT (rep != NULL, "invalid relative hashmap");
00031   if (rep->item->contains (x)) return rep->item (x);
00032   if ((!is_nil (rep->next)) && rep->next->contains (x))
00033     rep->item(x)= copy (rep->next[x]);
00034   return rep->item (x);
00035 }
00036 
00037 template <class T, class U> bool
00038 rel_hashmap_rep<T,U>::contains (T x) {
00039   if (item->contains (x)) return true;
00040   if (is_nil (next)) return false;
00041   return next->contains (x);
00042 }
00043 
00044 template <class T, class U> void
00045 rel_hashmap_rep<T,U>::extend () {
00046   next= rel_hashmap<T,U> (item, next);
00047   item= hashmap<T,U> (item->init);
00048 }
00049 
00050 template <class T, class U> void
00051 rel_hashmap_rep<T,U>::shorten () {
00052   ASSERT (!is_nil (next), "relative hashmap cannot be shortened");
00053   item= next->item;
00054   next= next->next;
00055 }
00056 
00057 template <class T, class U> void
00058 rel_hashmap_rep<T,U>::merge () {
00059   ASSERT (!is_nil (next), "relative hashmap cannot be merged");
00060   next->change (item);
00061   shorten ();
00062 }
00063 
00064 template <class T, class U> void
00065 rel_hashmap_rep<T,U>::find_changes (hashmap<T,U>& CH) {
00066   int i;
00067   rel_hashmap<T,U> h (item, next);
00068   list<hashentry<T,U> > remove;
00069   for (i=0; i<CH->n; i++) {
00070     list<hashentry<T,U> > l (CH->a[i]);
00071     while (!is_nil (l)) {
00072       if (h [l->item.key] == l->item.im)
00073        remove= list<hashentry<T,U> > (l->item, remove);
00074       l=l->next;
00075     }
00076   }
00077   while (!is_nil (remove)) {
00078     CH->reset (remove->item.key);
00079     remove= remove->next;
00080   }
00081 }
00082 
00083 template <class T, class U> void
00084 rel_hashmap_rep<T,U>::find_differences (hashmap<T,U>& CH) {
00085   int i;
00086   list<hashentry<T,U> > add;
00087   for (i=0; i<item->n; i++) {
00088     list<hashentry<T,U> > l (item->a[i]);
00089     while (!is_nil (l)) {
00090       if (!CH->contains (l->item.key))
00091        add= list<hashentry<T,U> > (l->item, add);
00092       l=l->next;
00093     }
00094   }
00095   while (!is_nil (add)) {
00096     CH (add->item.key)= next [add->item.key];
00097     add= add->next;
00098   }
00099   find_changes (CH);
00100 }
00101 
00102 template <class T, class U> void
00103 rel_hashmap_rep<T,U>::change (hashmap<T,U> CH) {
00104   int i;
00105   for (i=0; i<CH->n; i++) {
00106     list<hashentry<T,U> > l (CH->a[i]);
00107     while (!is_nil (l)) {
00108       item (l->item.key)= l->item.im;
00109       l=l->next;
00110     }
00111   }
00112 }
00113 
00114 template <class T, class U> tm_ostream&
00115 operator << (tm_ostream& out, rel_hashmap<T,U> H) {
00116   if (is_nil (H)) out << "(null)";
00117   else {
00118     while (!is_nil (H->next)) {
00119       out << H->item << LF;
00120       out << HRULE << LF;
00121       H= H->next;
00122     }
00123     out << H->item << LF;
00124   }
00125   return out;
00126 }
00127 
00128 #endif // defined REL_HASHMAP_CC