Map.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 # ifndef ALEPH_MAP_H
00045 # define ALEPH_MAP_H
00046 /*
00047         Aleph implementation of map C++ standard container
00048 */
00049 
00050 # include <stdlib.h>
00051 # include <ahFunction.H>
00052 # include <ahPair.H>
00053 # include <ah_stdc++_utils.H>
00054 # include <tpl_treapRk.H>
00055 
00056 
00057 namespace Aleph
00058 {
00059 
00060     template <class T1, class T2, class Compare>
00061 struct Compare_For_Map 
00062 {
00063       bool
00064   operator () (const Aleph::pair<T1, T2> & __x, 
00065             const Aleph::pair<T1, T2> & __y) const
00066   { 
00067     return Compare () (__x.first, __y.first); 
00068   }
00069 };
00070 
00103     template <class Key, 
00104            class Elem, 
00105            class Compare = Aleph::less<Key>,
00106            template <class, class> class Tree = Treap_Rk
00107     >
00108 class map
00109 {
00110 public:
00111 
00113   typedef Aleph::pair<Key, Elem> Pair;
00114 
00116   typedef Pair value_type;
00117 
00120   typedef typename map::value_type & reference;
00121 
00123   typedef const typename map::value_type & const_reference;
00124 
00125   typedef size_t size_type;
00126 
00128   typedef Key key_type;
00129 
00131   typedef Elem mapped_type;
00132 
00133 private:
00134 
00135   typedef Tree<Pair, Compare_For_Map<Key, Elem, Compare> > Tree_Type;
00136 
00137   typedef typename Tree_Type::Node Node;
00138 
00139   mutable Tree_Type tree;
00140 
00141   Node * search_in_tree (const Key & k)
00142   {
00143     return tree.search (Pair (k) );
00144   }
00145 
00146 public:
00147 
00152   class iterator
00153   {
00154   private:
00155 
00156     friend class map<Key, Elem>;
00157     
00158     typedef typename Tree_Type::Iterator Iterator;
00159     
00160     Iterator itor;
00161     bool underflow;
00162     bool overflow;
00163 
00164     void init_flags ()
00165     {
00166       if (itor.has_current () )
00167      underflow = overflow = false;
00168       else
00169      underflow = overflow = true;
00170     }
00171 
00172     void goto_begin ()
00173     {
00174       itor.reset_first ();
00175       init_flags ();
00176     }
00177 
00178     void goto_last ()
00179     {
00180       itor.reset_last ();
00181       init_flags ();
00182     }
00183 
00184     void goto_end ()
00185     {
00186       itor.reset_last ();
00187       init_flags ();
00188       itor.next ();
00189       overflow = true;
00190     }
00191 
00192     void forward ()
00193     {
00194       if (underflow)
00195      {
00196        goto_begin ();
00197        return;
00198      }
00199       
00200       itor.next ();
00201 
00202       if (not itor.has_current () )
00203      overflow = true;
00204     }
00205 
00206     void backward ()
00207     {
00208       if (overflow)
00209      {
00210        goto_last ();
00211        return;
00212      }
00213       
00214       itor.prev ();
00215 
00216       if (not itor.has_current () )
00217      underflow = true;
00218     }
00219 
00220     iterator (Tree_Type & _tree, Node * node) 
00221       : itor (_tree, node), underflow (false), overflow (false)
00222     {
00223       /* empty */
00224     }
00225 
00226   public:
00227 
00229     typedef typename map::value_type   value_type;
00230 
00232     typedef typename map::size_type    difference_type;
00233 
00235     typedef typename map::value_type * pointer;
00236 
00238     typedef typename map::reference    reference;
00239 
00241     iterator () { /* empty */ }
00242 
00243     iterator (Tree_Type & tree) : itor (tree)
00244     {
00245       init_flags ();
00246     }
00247 
00249     Pair & operator * ()
00250     {
00251       return KEY (itor.get_current () );
00252     }
00253 
00255     Pair * operator -> ()
00256     {
00257       return &KEY (itor.get_current () );
00258     }
00259 
00262     Pair & operator ++ ()
00263     {
00264       forward ();
00265 
00266       return KEY (itor.get_current () );
00267     }
00268 
00270     Pair & operator ++ (int)
00271     {
00272       Pair & retPair = KEY (itor.get_current () );
00273       forward ();
00274 
00275       return retPair;
00276     }
00277 
00280     Pair & operator -- ()
00281     {
00282       backward ();
00283 
00284       return KEY (itor.get_current () );
00285     }
00286 
00288     Pair & operator -- (int)
00289     {
00290       Pair & retPair = KEY (itor.get_current () );
00291       backward ();
00292 
00293       return retPair;
00294     }
00295     
00298     Pair & operator += (const size_type & n)
00299     {
00300       itor.reset_to_pos (itor.get_current_position () + n);
00301 
00302       return KEY (itor.get_current () );
00303     } 
00304 
00307     Pair & operator -= (const size_type & n)
00308     {
00309       itor.reset_to_pos (itor.get_current_position () - n);
00310 
00311       return KEY (itor.get_current () );
00312     } 
00313 
00315     bool operator == (const iterator & _itor) const
00316     {
00317       return itor == _itor.itor;
00318     }
00319 
00321     bool operator != (const iterator & _itor) const
00322     {
00323       return not (itor == _itor.itor);
00324     }
00325 
00326     bool verify (const map & _map) const
00327     {
00328       return itor.verify ( (Tree_Type*) &_map.tree); 
00329     }
00330 
00331     bool verify (const iterator & it) const
00332     {
00333       return itor.verify (it.itor);
00334     }
00335   };
00336 
00338   map () { /* empty */ }
00339  
00341   map (const map & c) 
00342   {
00343     tree.getRoot () = copyRec (c.tree.getRoot () );
00344   }
00345 
00361       template <typename Itor> 
00362   map (Itor beg, const Itor & end) 
00363   {
00364     while (beg != end)
00365       tree.insert (new Node (beg++) );
00366   }
00367 
00370   ~map () 
00371   { 
00372     destroyRec (tree.getRoot () );
00373   }  
00374 
00376   map & operator = (const map& c)
00377   {
00378     if (this == &c)
00379       return *this;
00380 
00381     destroyRec (tree.getRoot ());
00382 
00383     tree.getRoot () = copyRec (c.tree.getRoot ()); 
00384 
00385     return *this;
00386   }
00387 
00389   size_t size () const { return COUNT (tree.getRoot () ); }
00390 
00392   bool empty () const 
00393   {
00394     return size() == 0;
00395   }
00396 
00399   bool operator == (const map & c) const
00400   {
00401     if (size () != c.size () )
00402       return false;
00403 
00404     typename Tree_Type::Iterator itor1 (tree), itor2 (c.tree);
00405     
00406     while (itor1.has_current () and itor2.has_current () )
00407     {
00408       if (KEY (itor1.get_current () ) != KEY (itor2.get_current () ) )
00409      return false;
00410 
00411       itor1.next ();
00412       itor2.next ();
00413     }
00414     
00415     I (not itor1.has_current () and not itor2.has_current () );
00416 
00417     return true;
00418   }
00419 
00422   bool operator != (const map & c) const
00423   {
00424     return not *this == c;
00425   }
00426 
00429   bool operator < (const map & c) const
00430   {
00431     typename Tree_Type::Iterator itor1 (tree), itor2 (c.tree);
00432 
00433     while (itor1.has_current () and itor2.has_current () )
00434     {
00435       if (KEY (itor1.get_current () ) < KEY (itor2.get_current () ))
00436      return true;
00437       else if (KEY (itor2.get_current () ) < KEY (itor1.get_current () ))
00438      return false;
00439       
00440       // En este caso las claves sons iguales
00441       itor1.next ();
00442       itor2.next ();
00443     }
00444     
00445     if (not itor1.has_current ())
00446       return true;
00447 
00448     return false;
00449   }
00450 
00453   bool operator > (const map & c)
00454   {
00455     return not (*this == c or *this < c);
00456   }
00457 
00460   bool operator <= (const map & c)
00461   {
00462     return not (*this > c );
00463   }
00464 
00467   bool operator >= (const map & c)
00468   {
00469     return not (*this < c);
00470   }
00471 
00483   size_type count (const Key & key)
00484   {
00485     if (search_in_tree (key) != NULL)
00486       return 1;
00487 
00488     return 0;
00489   } 
00490 
00503   iterator find (const Key & key) 
00504   { 
00505     Node * p = search_in_tree (key);
00506 
00507     if (p == NULL)
00508       return end ();
00509 
00510     return iterator (tree, p);
00511   }
00515   iterator lower_bound (const Key & key)
00516   {
00517     Node * p = search_rank_parent (tree.getRoot (), Pair (key));
00518 
00519     return iterator (tree, p);
00520   }
00521 
00525   iterator upper_bound (const Key & key)
00526   {
00527     Node * p = search_rank_parent (tree.getRoot (), Pair (key));
00528 
00529     iterator upper (tree, p);
00530     
00531     if (KEY (p).first == key)
00532       upper.itor.next ();
00533 
00534     return upper;
00535   }
00536 
00539   void swap (map & c)
00540   {
00541     tree.swap (c.tree);
00542   }
00543 
00545   iterator begin ()
00546   {
00547     return iterator (tree);
00548   }
00549 
00551   iterator end ()
00552   {
00553     iterator last (tree);
00554     last.goto_end ();
00555 
00556     return last;
00557   }
00558 
00574   Aleph::pair<iterator, bool> insert (const Pair & key)
00575   {
00576     Node * node = new Node (key);
00577 
00578     if (tree.insert (node) == NULL)
00579     {
00580       delete node;
00581      
00582       return Aleph::pair<iterator, bool> (iterator (tree), false);
00583     }
00584 
00585     return Aleph::pair<iterator, bool> (iterator (tree, node), true);
00586   }
00587     
00609   iterator insert (iterator /* pos */, const Pair& key)
00610   {
00611     Node * node = new Node (key);
00612 
00613     if (tree.insert (node) == NULL)
00614     {
00615       delete node;
00616       return iterator (tree, tree.search(key));
00617     }
00618   
00619     return iterator (tree, node);
00620   }
00621 
00639       template <typename Itor>
00640   void insert (Itor beg, const Itor & end)
00641   {
00642     while (beg != end)
00643       insert (beg++);
00644   }
00645 
00657   size_type erase (const Key & key)
00658   {
00659     Node * p = tree.remove (key);
00660 
00661     if (p == NULL)
00662       return 0;
00663      
00664     delete p;
00665 
00666     return 1;
00667   }
00668 
00682   void erase (iterator pos)
00683   {
00684     erase (KEY (pos.itor.get_current ()).first);
00685   }
00686 
00700   iterator erase (const iterator & beg, const iterator & end)
00701   {
00702     Aleph::verify_iterators (beg, end);
00703     Aleph::verify_container_and_iterator (*this, beg);
00704 
00705     iterator ret_val = end;
00706 
00707     const size_t pos_beg = beg.itor.get_current_position ();
00708     const size_t pos_end = end.itor.get_current_position ();
00709 
00710     Node * removed_tree = tree.remove (pos_beg, pos_end - 1);
00711 
00712     destroyRec (removed_tree);
00713 
00714     return ret_val;
00715   }
00716 
00718   void clear ()
00719   {
00720     destroyRec (tree.getRoot());
00721   }
00722   
00723 private:
00724   
00725   struct Proxy
00726   {
00727     map  * map_ptr;
00728     Node * node;
00729     Key    key;
00730 
00731     Proxy (map * m_ptr, const Key & _key) : map_ptr (m_ptr), key (_key)
00732     {
00733       node = map_ptr->search_in_tree (key);
00734     }
00735 
00736     Proxy & operator = (const Elem & elem)
00737     {
00738       if (node == NULL)
00739         {
00740        node = new Node (Aleph::make_pair (key, elem));
00741        map_ptr->tree.insert (node);
00742      }
00743       else
00744         KEY (node).second = elem;
00745 
00746       return *this;
00747     }
00748 
00749     Proxy & operator = (const Proxy & proxy)
00750     {
00751       if (this == &proxy)
00752      return *this;
00753 
00754       if (proxy.node == NULL)
00755         throw std::domain_error("key not found");;
00756 
00757       if (map_ptr == proxy.map_ptr and key == proxy.key)
00758         return *this; // They are the same
00759 
00760       if (node == NULL)
00761         {
00762        node = new Node (KEY (proxy.node));
00763        map_ptr->tree.insert (node);
00764      } 
00765       else
00766         KEY (node).second = KEY (proxy.node).second;
00767 
00768       return *this;
00769     }
00770 
00771     operator Elem & () const
00772     {
00773       if (node == NULL)
00774         throw std::domain_error ("key not found");;
00775 
00776       return KEY (node).second;
00777     }    
00778   };
00779 
00780 public:
00781 
00782   const Proxy operator [] (const Key & key) const 
00783     Exception_Prototypes (std::domain_error)
00784   {
00785     return Proxy (this, key);
00786   }
00787 
00788   Proxy operator [] (const Key & key) 
00789     Exception_Prototypes (std::domain_error)
00790   {
00791     return Proxy (this, key);
00792   }
00793 };
00794 
00795 
00796 
00797 } // end namespace Aleph
00798 
00799 
00800 # endif // ALEPH_MAP_H

Leandro R. León