Vector.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 vector C++ standard container
00046 */
00047 
00048 # ifndef ALEPH_VECTOR_H
00049 # define ALEPH_VECTOR_H
00050 
00051 # include <tpl_dynArray.H>
00052 # include <ahIterator.H>
00053 # include <ah_stdc++_utils.H>
00054 
00055 namespace Aleph
00056 {
00057 
00058 template <class T> class vector;
00059 
00060     template <typename T> 
00061 typename iterator_traits<typename vector<T>::iterator>::difference_type 
00062 distance(typename vector<T>::iterator, typename vector<T>::iterator);
00063 
00087     template <typename T>
00088 class vector
00089 {
00090 public:
00091 
00093   typedef T value_type;
00094 
00096   typedef typename vector::value_type & reference;
00097 
00099   typedef const typename vector::value_type & const_reference;
00100 
00102   typedef size_t size_type;
00103 
00104 private:
00105 
00106   mutable DynArray<T> array;
00107 
00108   mutable size_type num_elem;
00109 
00110 public:
00111 
00116   class iterator 
00117   { 
00118     friend class vector<T>;
00119     
00120     static const int Invalid_Position = -1;
00121 
00122     mutable DynArray<T> * dyn_array_ptr;
00123 
00124     mutable size_type current_position;
00125 
00126     T cookie_data;
00127 
00128     iterator(const vector<T> & vec, const size_t & pos = 0)
00129       :  dyn_array_ptr(&vec.array), current_position(pos) 
00130     { 
00131       /* empty */ 
00132     }
00133 
00134     void set_pos(const size_t & pos)
00135     {
00136       current_position = num_elem;
00137     }
00138 
00139     int get_position() const { return current_position; }
00140 
00141     DynArray<T> * get_dyn_array_ptr() { return dyn_array_ptr; }
00142 
00143     T & access(const size_type & i)
00144     {
00145       if (i >= dyn_array_ptr->size())
00146      return cookie_data;
00147 
00148       return dyn_array_ptr->access(i);
00149     }
00150 
00151   public:
00152 
00154     typedef typename vector<T>::value_type   value_type;
00155 
00158     typedef int                              difference_type;
00159 
00161     typedef typename vector<T>::value_type * pointer;
00162 
00164     typedef typename vector<T>::reference    reference;
00165 
00167     iterator() : dyn_array_ptr(NULL), current_position(Invalid_Position) 
00168     { 
00169       /* empty */ 
00170     }
00171 
00173     iterator(const iterator & itor)
00174       : dyn_array_ptr(itor.dyn_array_ptr),
00175      current_position(itor.current_position) 
00176     { 
00177       /* empty */ 
00178     }
00179     
00181     iterator & operator = (const iterator & itor)
00182     {
00183       if (&itor == this)
00184      return *this;
00185 
00186       dyn_array_ptr = itor.dyn_array_ptr;
00187       current_position  = itor.current_position;
00188 
00189       return *this;
00190     }
00191 
00193     T & operator [] (const size_type & index)
00194     {
00195       current_position = index;
00196 
00197       return access(index);
00198     }
00199 
00202     iterator & operator = (const T & key)
00203     {
00204       access(current_position) = key;
00205 
00206       return *this;
00207     }
00208 
00210     T & operator * ()
00211     {
00212       return dyn_array_ptr->access(current_position);
00213     }
00214     
00216     T * operator -> ()
00217     {
00218       return & dyn_array_ptr->access(current_position);
00219     }
00220     
00223     T & operator ++ ()
00224     {
00225       current_position++;
00226 
00227       return access(current_position);
00228     }
00229 
00232     T & operator ++ (int)
00233     {
00234       T & return_value = access(current_position);
00235 
00236       current_position++;
00237 
00238       return return_value;
00239     }
00240 
00243     T & operator -- ()
00244     {
00245       current_position--;
00246 
00247       return access(current_position);
00248     }
00249 
00252     T & operator -- (int)
00253     {
00254       T& return_value = access(current_position);
00255 
00256       current_position--;
00257 
00258       return return_value;
00259     }
00260 
00262     T & operator += (const size_type & n)
00263     {
00264       current_position += n;
00265      
00266       return access(current_position);
00267     }
00268 
00270     T & operator -= (const size_type & n)
00271     {
00272       current_position -= n;
00273      
00274       return access(current_position);
00275     }
00276 
00279     bool operator < (const iterator & itor) const
00280     {
00281       return current_position < itor.current_position;
00282     }
00283     
00286     bool operator <= (const iterator & itor) const
00287     {
00288       return current_position <= itor.current_position;
00289     }
00290 
00293     bool operator > (const iterator & itor) const
00294     {
00295       return current_position > itor.current_position;
00296     }
00297     
00300     bool operator >= (const iterator& itor) const
00301     {
00302       return current_position >= itor.current_position;
00303     }
00304     
00307     bool operator == (const iterator & itor) const
00308     {
00309       return current_position == itor.current_position;
00310     }
00311     
00314     bool operator != (const iterator & itor) const
00315     {
00316       return current_position != itor.current_position;
00317     }    
00318     
00321     int operator - (const iterator & itor) const
00322     {
00323       return current_position - itor.current_position;
00324     }
00325 
00328     iterator operator + (const int & n) const
00329     {
00330       iterator ret_val(*this);
00331 
00332       ret_val.current_position += n;
00333 
00334       return ret_val;
00335     }
00336 
00337     bool verify(const DynArray<T> & array) const
00338     {
00339       return &array == dyn_array_ptr;
00340     }
00341 
00342     bool verify(const iterator & it) const
00343     {
00344       return dyn_array_ptr == it.dyn_array_ptr;
00345     }
00346   };
00347 
00349   vector() : array(0), num_elem(0) { /* empty */ }
00350 
00352   vector (const vector & c) : array(c.array), num_elem(c.num_elem)
00353   {
00354     // empty
00355   }
00356 
00358   vector (const size_type & num) : array(num), num_elem(num)
00359   {
00360     array.reserve(0, num_elem - 1);
00361   }
00362 
00365       template <typename Itor> explicit 
00366   vector (Itor beg, const Itor & end) : array(0), num_elem(0)
00367   {
00368     Aleph::verify_iterators(beg, end);
00369 
00370     while (beg != end)
00371       array[num_elem++] = beg++;
00372 
00373     I(num_elem == array.size());
00374   }
00375 
00377   vector (const size_type & num, const T & value) : array(num), num_elem(num)
00378   {
00379     array.reserve(0, num_elem - 1);
00380         
00381     for(size_type i = 0; i < num; i++)
00382       array.access(i) = value;
00383   }
00384 
00385   ~vector() { /* empty */ }
00386 
00388   const size_type & size() const { return num_elem; }
00389 
00391   bool empty() const { return num_elem == 0; }
00392 
00394   size_type max_size() const { return array.max_size(); }
00395 
00397   size_type capacity() const { return array.size(); }  
00398 
00400   void reserve (const size_type & num)
00401   {
00402     if (num < array.size())
00403       return;
00404 
00405     array.reserve(array.size(), array.size() + num);  
00406   }
00407 
00409   void resize (const size_type & num)
00410   {
00411     if (num < array.size())
00412       {
00413      num_elem = num;
00414      return;
00415       }
00416 
00417     reserve(num - array.size());
00418   }
00419     
00422   void resize (const size_type & num, const T & value)
00423   {
00424     if (num < array.size())
00425       {
00426      num_elem = num;
00427      return;
00428       }
00429 
00430     reserve(num - array.size());
00431 
00432     for (/* nothing */; num_elem < num; num_elem++)
00433       array.access(num_elem) = value;
00434   }
00435 
00437   vector & operator = (const vector & c)
00438   {
00439     if (this == &c)
00440       return *this;
00441 
00442     array = c.array;
00443     num_elem = c.num_elem;
00444 
00445     return *this;
00446   }
00447 
00449   void assign (const size_type & num, const T & value)
00450   {
00451     if (num > array.size())
00452       array.reserve(0, num - 1);
00453 
00454     num_elem = num;
00455 
00456     for(size_type i = 0; i < num; i++)
00457       array.access(i) = value;
00458   }
00459 
00462       template <typename Itor> 
00463   void assign (Itor beg, const Itor & end)
00464   {
00465     Aleph::verify_iterators(beg, end);
00466 
00467     num_elem = 0;
00468     while (beg < end)
00469       array[num_elem++] = beg++;
00470   }
00471 
00474   void swap(vector & c)
00475   {
00476     Aleph::swap(num_elem, c.num_elem);
00477     array.swap(c.array);
00478   }
00479     
00481   reference at(const size_type & idx) 
00482   { 
00483     return array[idx]; 
00484   }
00485 
00488   const_reference at(const size_type & idx) const 
00489   { 
00490     return array[idx]; 
00491   }
00492 
00494   reference operator [] (const size_type & idx) 
00495   { 
00496     return array.access(idx); 
00497   }
00498 
00500   const_reference operator [] (const size_type & idx) const 
00501   {
00502     return array.access(idx); 
00503   }
00504 
00507   reference front() const
00508   { 
00509     return array.access(0); 
00510   }
00511 
00514   reference back() const
00515   { 
00516     return array.access(num_elem - 1); 
00517   }
00518 
00521   iterator begin() const
00522   {
00523     return iterator (*this); 
00524   }
00525   
00528   iterator end() const
00529   { 
00530     return iterator (*this, num_elem); 
00531   }
00532 
00533 private:
00534 
00535   void open_gap(const size_t & position, const size_type & gap_len = 1)
00536   {
00537     const size_type old_size = array.size();
00538     array.reserve(old_size, old_size + gap_len - 1);
00539 
00540     if (position >= old_size)
00541       return;
00542 
00543     const size_t final_pos = position + gap_len;
00544     for (int i = array.size() - 1; i > final_pos; i--)
00545       array.access(i) = array.access(i - gap_len);
00546   }
00547 
00548 public:
00549 
00551   iterator insert(const iterator & pos, const T & value)
00552   {
00553     Aleph::verify_container_and_iterator(array, pos);
00554 
00555     open_gap(pos.get_position());
00556 
00557     array.access(pos.get_position()) = value;
00558   
00559     num_elem++;
00560 
00561     return pos;    
00562   }
00563 
00566   void insert(iterator pos, const size_type & len, const T & value)
00567   {
00568     Aleph::verify_container_and_iterator(array, pos);
00569 
00570     open_gap(pos.get_position(), len);
00571 
00572     for (int i = 0; i < len; i++, pos++, num_elem++)
00573       array.access(i) = value;
00574   }
00575 
00578       template <class Itor>
00579   void insert(const iterator & pos, Itor beg, const Itor & end)
00580   {
00581     Aleph::verify_container_and_iterators(array, pos, beg, end);
00582     
00583     size_type gap_len = Aleph::distance<T>(beg, end);
00584 
00585     open_gap(pos.get_position(), gap_len);
00586 
00587     num_elem += gap_len;
00588 
00589     for (int i = pos.get_position(); gap_len > 0; i++, gap_len--)
00590       array.access(i) = beg++;
00591   }
00592 
00594   void push_back (const T & value)
00595   {
00596     array[num_elem] = value;
00597     num_elem++;
00598   }
00599 
00600 private:
00601 
00602   void close_gap(const size_t & position, const size_type & len = 1)
00603   {
00604     for (int i = position; i < num_elem - len; i++)
00605       array.access(i) = array.access(i + len);
00606 
00607     num_elem -= len;
00608   }
00609 
00610 public:
00611 
00613   iterator erase (const iterator & pos)
00614   {
00615     Aleph::verify_container_and_iterator(array, pos);
00616 
00617     close_gap(pos.get_position());
00618 
00619     return iterator(*this, pos.get_position());
00620   }
00621 
00625   iterator erase (const iterator & beg, const iterator & end)
00626   {
00627     Aleph::verify_container_and_iterators(array, beg, end);
00628 
00629     const size_t gap_last  = 
00630       end.get_position() <= num_elem ? end.get_position() : num_elem;
00631     const size_t gap_start = beg.get_position();
00632     const size_t gap_len   = gap_last - gap_start;
00633 
00634     if (gap_start > gap_last)
00635       return iterator(*this, num_elem);
00636 
00637     close_gap(gap_start, gap_len);
00638 
00639     return iterator(*this, gap_start);
00640   }
00641 
00643   void pop_back() { num_elem--; }
00644 
00646   void clear() { num_elem = 0; }
00647 
00650   bool operator == (const vector & r) const
00651   {
00652     if (this == &r)
00653       return true;
00654 
00655     if (num_elem != r.num_elem)
00656       return false;
00657 
00658     const size_t len = Aleph::min( num_elem, r.num_elem);
00659 
00660     for (size_t i = 0; i < len; i++)
00661       if (array.access(i) != r.array.access(i))
00662      return false;
00663 
00664     return true;
00665   }
00666 
00668   bool operator != (const vector & r) const
00669   {
00670     return not (*this == r);
00671   }
00672   
00675   bool operator < (const vector & r) const
00676   {
00677     if (this == &r)
00678       return false;
00679 
00680     const bool l_smaller = num_elem < r.num_elem;
00681 
00682     const size_t len = l_smaller ? num_elem : r.num_elem;
00683 
00684     for (size_t i = 0; i < len; i++)
00685       if (array.access(i) < r.array.access(i))
00686      return true;
00687       else if (r.array.access(i) < array.access(i))
00688      return false; // ==> no son iguales 
00689 
00690     return l_smaller;
00691   }
00692 
00695   bool operator > (const vector & r) const
00696   {
00697     return r < *this;
00698   }
00699 
00703   bool operator <= (const vector & r) const
00704   {
00705     return not (r > *this);
00706   }
00707 
00711   bool operator >= (const vector & r) const
00712   {
00713     return not (*this < r);
00714   }
00715 };
00716 
00717 
00718 
00719     template <typename T> 
00720 typename iterator_traits<typename vector<T>::iterator>::difference_type 
00721 distance(typename vector<T>::iterator it1, typename vector<T>::iterator it2)
00722 {
00723   return it2 - it1;
00724 }
00725 
00726 } // end namespace Aleph
00727 
00728 # endif // ALEPH_VECTOR_H

Leandro R. León