Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Array.h

Go to the documentation of this file.
00001 // Copyright (C) 2002 Johan Hoffman and Anders Logg.
00002 // Licensed under the GNU GPL Version 2.
00003 
00004 #ifndef __ARRAY_H
00005 #define __ARRAY_H
00006 
00007 #include <signal.h>
00008 
00009 #include <dolfin/dolfin_log.h>
00010 #include <dolfin/General.h>
00011 
00012 namespace dolfin {
00013   
00015 
00054 
00055   template <class T> class Array {
00056   public:
00057     
00058     class Iterator;
00059     friend class Iterator;
00060     
00062     Array();
00063     
00065     Array(int size);
00066     
00068     ~Array();
00069     
00071     void init(int new_size);
00072     
00074     void resize(int new_size);
00075 
00077     void clear();
00078     
00080     T& operator() (int i) const;
00081 
00083     void operator= (const T& element);
00084    
00086     int size() const;
00087 
00089     bool empty() const;
00090         
00092     bool contains(const T& element);
00093     
00095     T& max() const;
00096 
00098     void remove(const T& element);
00099 
00101     void swap(int i, int j);
00102          
00104     Iterator begin() const;
00105 
00107 
00109     void reset();
00110     
00112     void setsize(int new_size);
00113     
00115     void init();
00116    
00118     int add(T element);
00119 
00121     void resize();
00122 
00128 
00129     class Iterator {
00130     public:
00131       
00133       Iterator();
00134       
00136       Iterator(const Array<T>& array);
00137 
00139       Iterator(const Array<T>& array, Index index);
00140 
00141       Iterator& operator++();
00142 
00143       Iterator& operator--();
00144 
00145       bool end() const;
00146       
00147       bool last() const;
00148 
00149       bool operator==(const Iterator& it);
00150       
00151       void operator=(Iterator& it);
00152 
00153       void operator=(const Iterator& it);
00154 
00155       int index() const;
00156       
00157       T& operator*() const;
00158       
00159       T* operator->() const;
00160       
00161       operator T*() const;
00162 
00163       T* pointer() const;
00164       
00165     private:
00166       
00167       T *array;
00168       T *element;
00169       int _index;
00170       int size;
00171       bool at_end;
00172       
00173     };
00174     
00175   private:
00176     
00177     T *array;
00178     int _size;
00179     
00180   };
00181 
00182   //---------------------------------------------------------------------------
00183   // Implementation of Array
00184   //---------------------------------------------------------------------------
00185   template <class T> Array<T>::Array()
00186   {
00187     //dolfin_debug("Array ctor");
00188 
00189     array = 0;
00190     _size = 0;
00191   }
00192   //---------------------------------------------------------------------------    
00193   template <class T> Array<T>::Array(int size)
00194   {
00195     //dolfin_debug("Array size ctor");
00196 
00197     array = 0;
00198     _size = 0;
00199     init(size);
00200   }
00201   //---------------------------------------------------------------------------    
00202   template <class T> Array<T>::~Array()
00203   {
00204     clear();
00205   }
00206   //---------------------------------------------------------------------------
00207   template <class T> void Array<T>::init(int new_size)
00208   {
00209     if ( array )
00210       clear();
00211     
00212     if ( new_size <= 0 )
00213       return;
00214     
00215     array = new T[new_size];
00216     _size = new_size;
00217   }
00218   //---------------------------------------------------------------------------    
00219   template <class T> void Array<T>::resize(int new_size)
00220   {
00221     if ( !array ) {
00222       init(new_size);
00223       return;
00224     }
00225     
00226     // Create new array and copy the elements
00227     T *new_array = new T[new_size];
00228     for (int i = 0; i < _size && i < new_size; i++)
00229       new_array[i] = array[i];
00230     
00231     // Update the old array with the new array
00232     delete [] array;
00233     array = new_array;
00234     _size = new_size;
00235   }
00236   //---------------------------------------------------------------------------    
00237   template <class T> void Array<T>::clear()
00238   {
00239     if ( array )
00240       delete [] array;
00241     array = 0;
00242     _size = 0;
00243   }
00244   //---------------------------------------------------------------------------    
00245   template <class T> T& Array<T>::operator() (int i) const
00246   {
00247     dolfin_assert(i >= 0);
00248     dolfin_assert(i < _size);
00249     return array[i];
00250   }
00251   //---------------------------------------------------------------------------    
00252   template <class T> void Array<T>::operator= (const T& element)
00253   {
00254     for (int i = 0; i < _size; i++)
00255       array[i] = element;
00256   }
00257   //---------------------------------------------------------------------------    
00258   template <class T> int Array<T>::size() const
00259   {
00260     return _size;
00261   }
00262   //---------------------------------------------------------------------------    
00263   template <class T> bool Array<T>::empty() const
00264   {
00265     return _size == 0;
00266   }
00267   //---------------------------------------------------------------------------    
00268   template <class T> bool Array<T>::contains(const T& element)
00269   {
00270     for (int i = 0; i < _size; i++)
00271       if ( array[i] == element )
00272         return true;
00273     return false;
00274   }
00275   //---------------------------------------------------------------------------    
00276   template <class T> void Array<T>::remove(const T& element)
00277   {
00278     for (int i = 0; i < _size; i++)
00279       if ( array[i] == element ) {
00280         array[i] = 0;
00281         return;
00282       }
00283     dolfin_error("Element is not in the array.");
00284   }
00285   //---------------------------------------------------------------------------  
00286   template <class T> T& Array<T>::max() const
00287   {
00288     int pos = 0;
00289     for (int i = 1; i < _size; i++)
00290       if ( array[pos] < array[i] )
00291         pos = i;
00292     
00293     return array[pos];
00294   }
00295   //---------------------------------------------------------------------------
00296   template <class T> void Array<T>::swap(int i, int j)
00297   {
00298     T tmp = array[i];
00299     array[i] = array[j];
00300     array[j] = tmp;
00301   }
00302   //---------------------------------------------------------------------------  
00303   template <class T> typename Array<T>::Iterator Array<T>::begin() const
00304     {
00305     return Iterator(*this);
00306   }
00307   //---------------------------------------------------------------------------    
00308   template <class T> void Array<T>::setsize(int new_size)
00309   {
00310     _size = new_size;
00311   }
00312   //---------------------------------------------------------------------------    
00313   template <class T> void Array<T>::reset()
00314   {
00315     for (int i = 0; i < _size; i++)
00316       array[i] = 0;
00317   }
00318   //---------------------------------------------------------------------------    
00319   template <class T> void Array<T>::init()
00320   {
00321     init(_size);
00322     reset();
00323   }
00324   //---------------------------------------------------------------------------    
00325   template <class T> int Array<T>::add(T element)
00326   {
00327     for (int i = 0; i < _size; i++)
00328       if ( !array[i] ) {
00329         array[i] = element;
00330         return i;
00331       }
00332 
00333     dolfin_segfault();
00334     dolfin_error("Array is full.");
00335     return -1;
00336   }
00337   //--------------------------------------------------------------------------- 
00338   template <class T> void Array<T>::resize()
00339   {
00340     if ( !array )
00341       return;
00342     
00343     // Count the number of used positions
00344     int new_size = 0;
00345     for (int i = 0; i < _size; i++)
00346       if ( array[i] )
00347         new_size++;
00348     
00349     if ( new_size == 0 ){
00350       clear();
00351       return;
00352     }
00353     
00354     // Copy and reallocate
00355     T *new_array = new T[new_size];
00356     int pos = 0;
00357     for (int i = 0; i < _size; i++)
00358       if ( array[i] )
00359         new_array[pos++] = array[i];
00360     delete [] array;
00361     array = new_array;
00362     _size = new_size;
00363   }
00364   //---------------------------------------------------------------------------
00365   // Implementatio of Array::Iterator
00366   //---------------------------------------------------------------------------
00367   template <class T> Array<T>::Iterator::Iterator()
00368   {
00369     array = 0;
00370     element = 0;
00371     _index = 0;
00372     size = 0;
00373     at_end = true;
00374   }
00375   //---------------------------------------------------------------------------      
00376   template <class T> Array<T>::Iterator::Iterator(const Array<T> &array)
00377   {
00378     if ( array._size > 0 ){
00379       element = array.array;
00380       at_end = false;
00381     }
00382     else{
00383       element = 0;
00384       at_end = true;
00385     }
00386     
00387     _index = 0;
00388     size = array._size;
00389     this->array = array.array;
00390   }
00391   //---------------------------------------------------------------------------      
00392   template <class T> Array<T>::Iterator::Iterator
00393   (const Array<T> &array, Index index)
00394   {
00395     switch (index) {
00396     case dolfin::first:
00397       
00398       if ( array._size > 0 ){
00399         element = array.array;
00400         at_end = false;
00401       }
00402       else{
00403         element = 0;
00404         at_end = true;
00405       }
00406       
00407       _index = 0;
00408       size = array._size;
00409       this->array = array.array;
00410       
00411       break;
00412 
00413     case dolfin::last:
00414       
00415       if ( array._size > 0 ){
00416         element = array.array + array._size - 1;
00417         at_end = false;
00418       }
00419       else{
00420         element = 0;
00421         at_end = true;
00422       }
00423       
00424       _index = array._size - 1;
00425       size = array._size;
00426       this->array = array.array;
00427 
00428       break;
00429       
00430     default:
00431       
00432       dolfin_error("Unknown iterator position.");
00433 
00434     }      
00435 
00436   }
00437   //---------------------------------------------------------------------------      
00438   template <class T> typename Array<T>::Iterator::Iterator& 
00439   Array<T>::Iterator::operator++()
00440   {
00441     if ( _index == (size - 1) )
00442       at_end = true;
00443     else {
00444       at_end = false;
00445       _index++;
00446     }
00447     
00448     element = array + _index;
00449     
00450     return *this;
00451   }
00452   //---------------------------------------------------------------------------      
00453   template <class T> typename Array<T>::Iterator::Iterator& 
00454   Array<T>::Iterator::operator--()
00455   {
00456     if ( _index == 0 )
00457       at_end = true;
00458     else {
00459       at_end = false;
00460       _index--;
00461     }
00462     
00463     element = array + _index;
00464     
00465     return *this;
00466   }
00467   //---------------------------------------------------------------------------      
00468   template <class T> bool Array<T>::Iterator::end() const
00469   {
00470     return at_end;
00471   }
00472   //---------------------------------------------------------------------------      
00473   template <class T> bool Array<T>::Iterator::last() const
00474   {
00475     return _index == (size - 1);
00476   }
00477   //---------------------------------------------------------------------------
00478   template <class T> bool Array<T>::Iterator::operator==(const Iterator& it)
00479   {
00480     return element == it.element;
00481   }
00482   //---------------------------------------------------------------------------      
00483   template <class T> void Array<T>::Iterator::operator=(Iterator& it)
00484   {
00485     array   = it.array;
00486     element = it.element;
00487     _index  = it._index;
00488     size    = it.size;
00489     at_end  = it.at_end;
00490   }
00491   //---------------------------------------------------------------------------
00492   template <class T> void Array<T>::Iterator::operator=(const Iterator& it)
00493   {
00494     array   = it.array;
00495     element = it.element;
00496     _index  = it._index;
00497     size    = it.size;
00498     at_end  = it.at_end;
00499   }
00500   //---------------------------------------------------------------------------
00501   template <class T> int Array<T>::Iterator::index() const
00502   {
00503     return _index;
00504   }
00505   //---------------------------------------------------------------------------      
00506   template <class T> T& Array<T>::Iterator::operator*() const
00507   {
00508     return *element;
00509   }
00510   //---------------------------------------------------------------------------      
00511   template <class T> T* Array<T>::Iterator::operator->() const
00512   {
00513     return element;
00514   }
00515   //---------------------------------------------------------------------------      
00516   template <class T> Array<T>::Iterator::operator T*() const
00517   {
00518     return element;
00519   }
00520   //---------------------------------------------------------------------------      
00521   template <class T> T* Array<T>::Iterator::pointer() const
00522   {
00523     return element;
00524   }
00525   //---------------------------------------------------------------------------      
00526   
00527 }
00528 
00529 #endif


Documentation automatically generated with Doxygen on 10 Sep 2004.