List.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 /*
00045      Aleph implementation of list C++ standard container
00046 */
00047 
00048 # ifndef ALEPH_LIST_H
00049 # define ALEPH_LIST_H
00050 
00051 # include <ah_stdc++_utils.H>
00052 # include <tpl_dnode.H>
00053 # include <tpl_sort_utils.H>
00054 
00055 
00056 namespace Aleph
00057 {
00058 
00066     template <class T>
00067 class list
00068 {
00069   mutable Dnode<T> dlist;
00070 
00071   typedef Dnode<T> Node;
00072 
00073 public:
00074 
00076   typedef T value_type;
00077 
00079   typedef typename list::value_type & reference;
00080 
00082   typedef const typename list::value_type & const_reference;
00083 
00085   typedef size_t size_type;
00086 
00087 private:
00088 
00089   mutable size_type num_elem;
00090 
00091   mutable bool num_elem_is_updated;
00092 
00093   void reset_num_elem(const size_type & num = 0)
00094   {
00095     num_elem = num;
00096     num_elem_is_updated = true;
00097   }
00098 
00099   void update_num_elem()
00100   {
00101     I(not num_elem_is_updated);
00102 
00103     size_type counter = 0;
00104 
00105     for (typename Dnode<T>::Iterator it(dlist); it.has_current(); it.next())
00106       ++counter;
00107 
00108     num_elem = counter;
00109     num_elem_is_updated = true;
00110   }
00111 
00112 public:
00113 
00119   class iterator
00120   {
00121     friend class list<T>;
00122 
00123     typedef typename Dnode<T>::Iterator Iterator;
00124     
00125     Iterator itor;
00126 
00127     bool underflow;
00128     bool overflow;
00129 
00130     void init_flags()
00131     {
00132       if (itor.has_current())
00133      underflow = overflow = false;
00134       else
00135      underflow = overflow = true;
00136     }
00137 
00138     iterator(Dnode<T> & __list) : itor(__list)
00139     {
00140       init_flags();
00141     }
00142 
00143     void goto_begin()
00144     {
00145       itor.reset_first();
00146       init_flags();
00147     }
00148 
00149     void goto_last()
00150     {
00151       itor.reset_last();
00152       init_flags();
00153     }
00154 
00155     void goto_end()
00156     {
00157       itor.reset_last();
00158       init_flags();
00159       itor.next();
00160       overflow = true;
00161     }
00162 
00163     void forward()
00164     {
00165       if (underflow)
00166      {
00167        goto_begin();
00168        return;
00169      }
00170       
00171       itor.next();
00172 
00173       if (not itor.has_current())
00174      overflow = true;
00175     }
00176 
00177     void backward()
00178     {
00179       if (overflow)
00180      {
00181        goto_last();
00182        return;
00183      }
00184       
00185       itor.prev();
00186 
00187       if (not itor.has_current())
00188      underflow = true;
00189     }
00190 
00191   public:
00192 
00194     typedef typename list::value_type   value_type;
00195 
00198     typedef int                         difference_type;
00199 
00201     typedef typename list::value_type * pointer;
00202 
00204     typedef typename list::reference    reference;
00205 
00207     iterator() : underflow(false), overflow(false) { /* empty */ }
00208 
00210     T & operator *()
00211     {
00212       return itor.get_current()->get_data();
00213     }
00214 
00216     T * operator ->()
00217     {
00218       return & itor.get_current()->get_data();
00219     }
00220 
00223     T & operator ++()
00224     {
00225       forward();
00226 
00227       return itor.get_current()->get_data();
00228     }
00229 
00232     T & operator ++ (int)
00233     {
00234       T & return_value = itor.get_current()->get_data();
00235       forward();
00236 
00237       return return_value;
00238     }
00239 
00242     T & operator --()
00243     {
00244       backward();
00245 
00246       return itor.get_current()->get_data();
00247     }
00248 
00251     T & operator -- (int)
00252     {
00253       T & return_value = itor.get_current()->get_data();
00254       backward();
00255 
00256       return return_value;
00257     }
00258     
00260     T & operator += (const size_type & n)
00261     {
00262       for (int i = 0; i < n; ++i)
00263      forward();
00264 
00265       return itor.get_current()->get_data();
00266     } 
00267 
00269     T & operator -= (const size_type & n)
00270     {
00271       for (int i = 0; i < n; ++i)
00272      backward();
00273 
00274       return itor.get_current()->get_data();
00275     } 
00276 
00278     bool operator == (const iterator & __itor)
00279     {
00280       return itor == __itor.itor;
00281     }
00282 
00284     bool operator != (const iterator& __itor)
00285     {
00286       return itor != __itor.itor;
00287     }
00288 
00289     bool verify (const list<T> & list) const
00290     {
00291       return itor.verify((Dlink*)(&list.dlist));
00292     }
00293 
00294     bool verify(const iterator & it) const
00295     {
00296       return itor.verify(it.itor);
00297     }
00298   }; // end class iterator
00299 
00300 private:
00301 
00302   void copy(const list& _list)
00303   {
00304     I(dlist.is_empty());
00305     I(num_elem == 0);
00306 
00307     for (typename Dnode<T>::Iterator it(_list.dlist); 
00308       it.has_current(); it.next())
00309       {
00310      Node * node = new Node(it.get_current()->get_data());
00311 
00312      dlist.append(node);
00313      ++num_elem;
00314       }
00315   }
00316 
00317 public:
00318 
00320   list() : num_elem(0), num_elem_is_updated(true) { /* empty */ }
00321 
00323   list(const list & c) : num_elem(0), num_elem_is_updated(true)
00324   {
00325     copy(c);
00326   }
00327 
00330   list(const size_type & num) : num_elem(0), num_elem_is_updated(true)
00331   {
00332     for (/* nothing */; num_elem < num; ++num_elem)
00333       dlist.append(new Node);
00334    }
00335 
00347   list(const size_type & num, const T & value) 
00348     : num_elem(0), num_elem_is_updated(true)
00349   {
00350     for (/* nothing */; num_elem < num; ++num_elem)
00351       dlist.append(new Node(value));
00352   }
00353 
00368       template <class Itor>
00369   list(Itor beg, const Itor & end) 
00370     : num_elem(0), num_elem_is_updated(true)
00371   {
00372     Aleph::verify_iterators(beg, end);
00373 
00374     while (beg != end)
00375       {
00376      dlist.append(new Node(beg++));
00377      ++num_elem;
00378       }
00379   }
00380 
00381   ~list() 
00382   {
00383     clear();
00384   }
00385 
00387   size_type size() 
00388   {
00389     if (not num_elem_is_updated)
00390       update_num_elem();
00391 
00392     return num_elem;
00393   }
00394 
00396   bool empty() const
00397   {
00398     return dlist.is_empty();
00399   }
00400 
00403   bool operator == (const list & c) const
00404   {
00405     if (this == &c)
00406       return true;
00407 
00408     if (num_elem_is_updated and c.num_elem_is_updated)
00409       if (num_elem != c.num_elem)
00410      return false;
00411 
00412     typename Dnode<T>::Iterator it_l(*this), it_r(c.dlist);
00413 
00414     while (it_l.has_current() and it_r.has_current())
00415       {
00416      if (it_l.get_current()->get_data() != it_r.get_current()->get_data())
00417        return false;
00418 
00419      it_l.next();
00420      it_r.next();
00421       }
00422 
00423     if (it_l.is_empty() and it_r.is_empty())
00424       return true;
00425     
00426     return false;
00427   }
00428 
00431   bool operator != (const list & c) const
00432   {
00433     return not (*this == c);
00434   }
00435 
00438   bool operator < (const list & c) const
00439   {
00440     if (this == &c)
00441       return false;
00442 
00443     typename Dnode<T>::Iterator it_l(*this);
00444     typename Dnode<T>::Iterator it_r(c);
00445 
00446     while (it_l.has_current() and it_r.has_current())
00447       {
00448      if (it_l.get_current()->get_data() < it_r.get_current()->get_data())
00449        return true;
00450      else if (it_r.get_current()->get_data() < 
00451            it_l.get_current()->get_data())
00452        return false; // no son iguales
00453 
00454      it_l.next();
00455      it_r.next();
00456       }
00457 
00458     return it_l.is_empty();
00459   }
00460 
00463   bool operator > (const list & c) const
00464   {
00465     return c < *this;
00466   }
00467 
00470   bool operator <= (const list & c) const
00471   {
00472     return not (c > *this );
00473   }
00474 
00477   bool operator >= (const list & c) const
00478   {
00479     return not (*this < c);
00480   }
00481 
00484   list & operator = (const list & c)
00485   {
00486     if (this == &c)
00487       return *this;
00488 
00489     clear();
00490     copy(c);
00491   }
00492 
00502   void assign(const size_type & num, const T & value)
00503   {
00504     clear();
00505     
00506     for (int n = 0; n < num; ++n)
00507       push_back(value);
00508   }
00509 
00520       template <typename Itor>
00521   void assign (Itor beg, const Itor & end)
00522   {
00523     Aleph::verify_iterators(beg, end);
00524 
00525     clear();
00526     
00527     while (beg != end)
00528       push_back(beg++);
00529   }
00530     
00533   void swap(list & c)
00534   {
00535     dlist.swap(&c.dlist);
00536     Aleph::swap(num_elem, c.num_elem);
00537     Aleph::swap(num_elem_is_updated, c.num_elem_is_updated);
00538   }
00539 
00541   reference front() const
00542   {
00543     return dlist.get_next()->get_data();
00544   }
00545 
00547   reference back() const
00548   {
00549     return dlist.get_prev()->get_data();
00550   }
00551 
00554   iterator begin() const
00555   {
00556     return iterator(dlist);
00557   }
00558   
00561   iterator end() const
00562   {
00563     iterator _itor(dlist);
00564     _itor.goto_end();
00565 
00566     return _itor;
00567   }
00568  
00572   iterator insert(const iterator & pos, const T & value)
00573   {
00574     Aleph::verify_container_and_iterator(*this, pos);
00575 
00576     Node * new_node = new Node(value);
00577 
00578     Node * current_node = pos.itor.get_current();
00579 
00580     current_node->append(new_node);
00581 
00582     pos.itor.set(new_node);
00583 
00584     ++num_elem;
00585 
00586     return pos;
00587   }
00588 
00591   void insert(iterator pos, const size_type & num, const T & value)
00592   {
00593     Aleph::verify_container_and_iterator(*this, pos);
00594 
00595     Node new_list;
00596 
00597     try
00598       {
00599      for (int i = 0; i < num; ++i)
00600        new_list.append (new Node(value));
00601 
00602      Node * current_node = pos.itor.get_current();
00603      current_node->insert_list(&new_list);
00604      num_elem += num;
00605       }
00606     catch (...)
00607       {
00608      new_list.remove_all_and_delete();
00609      throw;
00610       }
00611   }
00612 
00615       template <class Itor>
00616   void insert(iterator pos, Itor beg, const Itor & end)
00617   {
00618     Aleph::verify_container_and_iterator(*this, pos);
00619     Aleph::verify_iterators(beg, end);
00620 
00621     Node new_list;
00622     try
00623       {
00624      while (beg != end)
00625        {
00626          new_list.append(new Node(beg++));
00627          ++num_elem;
00628        }
00629 
00630      Node * current_node = pos.itor.get_current();
00631      current_node->insert_list(&new_list);
00632       }
00633     catch (...)
00634       {
00635      new_list.remove_all_and_delete();
00636      throw;
00637       }
00638   }
00639 
00641   void push_front(const T & value)
00642   {
00643     dlist.insert(new Node(value));
00644     ++num_elem;
00645   }
00646 
00647   void push_back(const T & value)
00648   {
00649     dlist.append(new Node(value));
00650     ++num_elem;
00651   }
00652 
00654   void remove(const T & value)
00655   {
00656     for (typename Dnode<T>::Iterator it(dlist); it.has_current(); /* nothing */)
00657       if (it.get_current()->get_data() == value)
00658      {
00659        delete it.del();
00660        --num_elem;
00661      }
00662       else
00663      it.next();
00664   }
00665 
00667   iterator erase(iterator pos)
00668   {
00669     Aleph::verify_container_and_iterator(*this, pos);
00670 
00671     delete pos.itor.del();
00672     --num_elem;
00673 
00674     return pos;
00675   }
00676 
00680   iterator erase(iterator beg, const iterator & end)
00681   {
00682     Aleph::verify_container_and_iterator(*this, beg);
00683     Aleph::verify_iterators(beg, end);
00684 
00685     while (beg != end)
00686       {
00687      delete  beg.itor.del();
00688      --num_elem;
00689       }
00690 
00691     return beg;
00692   }
00693 
00695   void pop_front()
00696   {
00697     delete dlist.remove_next();
00698     num_elem--;
00699   }
00700 
00702   void pop_back()
00703   {
00704     delete dlist.remove_prev();
00705     --num_elem;
00706   }
00707 
00709   void clear()
00710   {
00711     dlist.remove_all_and_delete();
00712     reset_num_elem();
00713   }
00714 
00733   void resize(size_type num, const T & t = T())
00734   {
00735     if (num == size())
00736       return;
00737     
00738     if (num < num_elem)
00739       {
00740      while (num_elem > num)
00741        {
00742          delete dlist.remove_prev();
00743          --num_elem;
00744        }
00745 
00746      return;
00747       }
00748 
00749     iterator itor(end());
00750     --itor;
00751     insert(itor, num - num_elem, t);
00752   }
00753 
00756       template <class Op>
00757   void unique(const Op & op) 
00758   {
00759     reset_num_elem(); // recordar que coloca num_elem = 0
00760     
00761     for (typename Dnode<T>::Iterator it1(dlist); it1.has_current(); 
00762       it1.next(), ++num_elem)
00763       {
00764      typename Dnode<T>::Iterator it2(it1); it2.next(); 
00765 
00766      while (it2.has_current())
00767        if (op(it1.get_current()->get_data(), it2.get_current()->get_data()))
00768          delete it2.del();
00769        else
00770          break;
00771       }
00772   }
00773 
00775   void unique()  
00776   {
00777     unique(Aleph::equal_to<T>());
00778   }
00779 
00792   void splice(iterator pos, list & l)
00793   {
00794     Aleph::verify_container_and_iterator(*this, pos);
00795 
00796     pos.itor.get_current()->insert_list(&l.dlist);
00797 
00798     num_elem_is_updated = l.num_elem_is_updated;
00799     num_elem += l.num_elem;
00800 
00801     l.reset_num_elem();
00802 
00803     I(l.dlist.is_empty());
00804   }
00805 
00819   void splice(iterator pos, list & src_list, iterator src_pos)
00820   {
00821     Aleph::verify_container_and_iterator(*this, pos);
00822     Aleph::verify_container_and_iterator(src_list, src_pos);
00823 
00824     pos.itor.get_current()->insert(src_pos.itor.del());
00825     --src_list.num_elem;
00826     ++num_elem;
00827   }
00828 
00831   void splice(iterator pos, list & src_list, 
00832            iterator src_beg, const iterator & src_end)
00833   {
00834     Aleph::verify_container_and_iterator(*this, pos);
00835     Aleph::verify_container_and_iterator(src_list, src_beg);
00836     Aleph::verify_iterators(src_beg, src_end);    
00837 
00838     Dlink list_to_insert;
00839     src_list.dlist.cut_list(src_beg.itor.get_current(), &list_to_insert);
00840 
00841     Dlink remaining_list;
00842     list_to_insert.cut_list(src_end.itor.get_current(), &remaining_list);
00843     
00844     pos.itor.get_current()->insert_list(&list_to_insert);
00845     num_elem_is_updated = false;
00846 
00847     src_list.dlist.concat_list(&remaining_list);
00848     src_list.num_elem_is_updated = false;
00849   }
00850 
00852       template <class Cmp>
00853   void sort(const Cmp &)
00854   {
00855     quicksort<T, Cmp>(dlist); 
00856   }
00857 
00859   void sort()
00860   {
00861     sort(Aleph::less<T>()); 
00862   }
00863 
00865       template <class Cmp>
00866   void merge(list & l, const Cmp &)
00867   {
00868     Dnode<T> result;
00869 
00870     Aleph::merge_lists<T, Cmp>(dlist, l.dlist, result);
00871 
00872     dlist.swap(&result);
00873 
00874     num_elem += l.num_elem;
00875 
00876     l.reset_num_elem();
00877 
00878     I(l.dlist.is_empty());
00879   }
00880 
00882   void merge(list & l)
00883   {
00884     merge(l, Aleph::less<T>());
00885   }
00886 
00888   void reverse()
00889   {
00890     reset_num_elem(dlist.reverse_list());
00891   }
00892 };
00893 
00894 
00895     template <typename T>
00896 typename list<T>::size_type distance(typename list<T>::iterator it1, 
00897                          typename list<T>::iterator it2)
00898 {
00899   typename list<T>::size_type counter = 0;
00900 
00901   while (it1 != it2)
00902     {
00903       counter++;
00904       it1++;
00905     }
00906 
00907   return counter;
00908 }
00909 
00910 } // end namespace Aleph
00911 
00912 # endif // ALEPH_LIST_H

Leandro R. León