array.hh

00001 #ifndef DUNE_ARRAY_HH
00002 #define DUNE_ARRAY_HH
00003 
00004 #include<iostream>
00005 #include<iomanip>
00006 #include<string>
00007 #include<cassert>
00008 
00009 #include<rpc/rpc.h>
00010 #include"exceptions.hh"
00011 
00012 namespace Dune 
00013 {
00019 
00020   template <class T> 
00021   class Array {
00022   public:
00023   
00027       class Iterator {  
00028       private:          
00029           T* p;         // Iterator ist Zeiger auf Feldelement
00030 
00031       public:        
00033           Iterator();
00034  
00036           bool operator!= (const Iterator& x);
00037 
00039           bool operator== (const Iterator& x);
00040 
00042           Iterator operator++ ();   // prefix Stroustrup p. 292
00043           
00045           Iterator operator++ (int);// postfix
00046 
00048           const T& operator* () const;
00049 
00051           const T* operator-> () const; // Stroustrup p. 289
00052 
00053           friend class Array<T>;
00054         } ;
00055 
00057         Iterator begin () const; 
00058 
00060         Iterator end () const;
00061 
00063         Array();
00064         
00066         explicit Array(int m);
00067 
00069         Array (const Array<T>&);
00070 
00072         ~Array();
00073 
00075         Array<T>& operator= (const Array<T>&);
00076 
00078         Array<T>& operator= (const T& a);
00079 
00081         void resize (int m);
00082 
00084       void realloc (int m) {resize(m);}
00085 
00087       void swap ( Array<T> &copy)
00088       {
00089         T *tmp = copy.p;
00090         copy.p = p;
00091         p = tmp;
00092        
00093         int fake=copy.n;
00094         copy.n = n;
00095         n = fake;
00096       }
00097       
00099       int size () const;
00100 
00102       void set(const T& v) {
00103           for (int i=0; i<size(); ++i)
00104               (*this)[i] = v;
00105       }
00106 
00108       T& operator[](int i);
00109 
00111       const T& operator[](int i) const;
00112 
00114       typedef T MemberType;  
00115       typedef T value_type; // definition conforming to STL  
00116 
00123       void print (int k, std::string s, std::string row)
00124         {
00125           char buf[96];
00126           std::cout << s << " size=" << n << " {" << std::endl;
00127           for (int i=0; i<n/k; i++)
00128                 {
00129                   sprintf(buf,"%4d",k*i);
00130                   std::cout << buf << " " << row << " ";
00131                   for (int j=i*k; j<(i+1)*k; j++)
00132                         {
00133                           sprintf(buf,"%10.3E ",p[j]);
00134                           std::cout << buf;
00135                         }
00136                   std::cout << std::endl;
00137                 }
00138           int i = (n/k)*k;
00139           if (i<n)
00140                 {
00141                   sprintf(buf,"%4d",i);
00142                   std::cout << buf << " " << row << " ";
00143                   for (int j=i; j<n; j++)
00144                         {
00145                           sprintf(buf,"%10.3E ",p[j]);
00146                           std::cout << buf;
00147                         }
00148                   std::cout << std::endl;
00149                 }
00150           std::cout << "}" << std::endl;          
00151         }
00152 
00155       bool processXdr(XDR *xdrs)
00156       {
00157         if(xdrs != NULL)
00158         {
00159           int len = n;
00160           xdr_int( xdrs, &len );
00161           if(len != n) resize(len);
00162           xdr_vector(xdrs,(char *) p,n,sizeof(T),(xdrproc_t)xdr_double);
00163           return true;
00164         }
00165         else 
00166           return false;
00167       }
00168     
00169       T * raw()
00170       {
00171         return p;
00172       }
00173   protected:
00174       int n;  // Anzahl Elemente; n=0 heisst, dass kein array allokiert ist!
00175       T *p;   // Zeiger auf built-in array
00176   } ;
00177 
00178 
00180   template<class T>
00181   inline typename Array<T>::Iterator Array<T>::begin () const
00182   {
00183         Iterator tmp;  // hat Zeiger 0
00184         tmp.p = p;     // Zeiger auf Feldelement 0
00185         return tmp;
00186   }
00187   
00189   template<class T>
00190   inline typename Array<T>::Iterator Array<T>::end () const
00191   {
00192         Iterator tmp;
00193         tmp.p = &(p[n]); // Zeiger auf Feldelement NACH letztem !
00194         return tmp;      // das funktioniert: Stroustrup p. 92.
00195   }
00196 
00200   template <class T>
00201   inline Array<T>::~Array () 
00202   { 
00203         if (n>0) delete[] p; 
00204   }
00205   
00209   template <class T>
00210   inline Array<T>::Array () : n(0), p(0) {}
00211   
00215   template <class T>
00216   inline Array<T>::Array (int m) : n(m) ,p(0)
00217   {
00218         if (n<=0)
00219           {
00220                 n = 0;
00221                 return;
00222           }
00223         try {
00224           p = new T[n];
00225         }
00226         catch (std::bad_alloc) {
00227             DUNE_THROW(OutOfMemoryError, "Not enough memory!");
00228         }
00229   }
00230 
00234   template <class T>
00235   inline void Array<T>::resize (int m)
00236   {
00237         if (m!=n)
00238           {
00239                 if (n>0) 
00240                 {
00241                   delete[] p;
00242                   p = NULL;
00243                 }
00244                 n = m;
00245                 if (n==0) 
00246                 {
00247                   p = NULL;
00248                   return;
00249                 }
00250                 try {
00251                   p = new T[n];
00252                 }
00253                 catch (std::bad_alloc) {
00254                     DUNE_THROW(OutOfMemoryError, "Not enough memory!");
00255                 }
00256           }
00257      return;    
00258   }
00259 
00260   /* \brief Copy-constructor
00261      Implements deep copy.
00262   */
00263   template <class T>
00264   inline Array<T>::Array (const Array<T>& a)
00265   {
00266         // Erzeuge Feld mit selber Groesse wie a
00267         n = a.n;
00268         if (n>0)
00269           {
00270                 try {
00271                   p = new T[n];
00272                 }
00273                 catch (std::bad_alloc) {
00274                     DUNE_THROW(OutOfMemoryError, "Not enough memory!");
00275                 }
00276           }
00277 
00278         // und kopiere Elemente
00279         for (int i=0; i<n; i=i+1) p[i]=a.p[i];
00280   }
00281 
00282   /* \brief Assignment operator
00283    */
00284   template <class T>
00285   inline Array<T>& Array<T>::operator= (const Array<T>& a)
00286   {
00287         if (&a!=this) // nur bei verschiedenen Objekten was tun
00288           {
00289                 if (n!=a.n)
00290                   {
00291                         // allokiere fuer this ein Feld der Groesse a.n
00292                         if (n>0) delete[] p; // altes Feld loeschen
00293                         n = a.n;
00294                         if (n>0)
00295                           {
00296                                 try {
00297                                   p = new T[n];
00298                                 }
00299                                 catch (std::bad_alloc) {
00300                                     DUNE_THROW(OutOfMemoryError, "Not enough memory!");
00301                                 }
00302                           }
00303                   }
00304                 for (int i=0; i<n; i++) p[i]=a.p[i];
00305           }
00306         return *this; // Gebe Referenz zurueck damit a=b=c; klappt
00307   }
00308 
00309   /* \brief Assignment operator
00310      All elements of the Array get the value a
00311   */
00312   template <class T>
00313   inline Array<T>& Array<T>::operator= (const T& a)
00314   {
00315         for (int i=0; i<n; i++) p[i]=a;
00316         return *this; // Gebe Referenz zurueck damit a=b=c; klappt
00317   }
00318   
00319   /* \brief Access operator
00320      Accessing of elements in Array. With bounds check.
00321    */
00322   template <class T>
00323   inline T& Array<T>::operator[] (int i)
00324   {
00325       assert( ((i<0) || (i>=size()) ? (std::cout << std::endl << i << " i|size " << size() << std::endl, 0) : 1));
00326       return p[i];
00327   }
00328 
00329   /* \brief Access operator
00330      Accessing of elements in Array. With bounds check. Const version
00331   */
00332   template <class T>
00333   inline const T& Array<T>::operator[] (int i) const
00334   {
00335       assert(i>=0);
00336       assert(i<size());
00337       return p[i];
00338   }
00339 
00340   /* \brief Size of Array
00341    */
00342   template <class T>
00343   inline int Array<T>::size () const
00344   { 
00345         return n; 
00346   }
00347 
00348   /* \brief Output operator
00349    */
00350   template <class T>
00351   std::ostream& operator<< (std::ostream& s, const Array<T>& a)
00352   {
00353         s << "array " << a.size() << " elements = [" << std::endl;
00354         for (int i=0; i<a.size(); i++)
00355           s << "    " << i << "  " << a[i] << std::endl;
00356         s << "]" << std::endl;
00357         return s;
00358   }
00359 
00361   template<class T>
00362   inline Array<T>::Iterator::Iterator () 
00363   {
00364         p=0; // nicht initialisierter Iterator
00365   }
00366 
00368   template<class T>
00369   inline bool Array<T>::Iterator::operator!= 
00370   (const typename Array<T>::Iterator& x)
00371   {
00372         return p != x.p;
00373   }
00374 
00376   template<class T>
00377   inline bool Array<T>::Iterator::operator== 
00378   (const typename Array<T>::Iterator& x)
00379   {
00380         return p == x.p;
00381   }
00382 
00384   template<class T>
00385   inline typename Array<T>::Iterator Array<T>::Iterator::operator++ () // prefix
00386   {
00387         p++;  // C Zeigerarithmetik: p zeigt auf naechstes Feldelement
00388         return *this;
00389   }
00390 
00392   template<class T>
00393   inline typename Array<T>::Iterator Array<T>::Iterator::operator++ (int) // postfix
00394   {
00395         Iterator tmp = *this;
00396         ++*this;
00397         return tmp;
00398   }
00399 
00401   template<class T>
00402   inline const T& Array<T>::Iterator::operator* () const
00403   {
00404         return *p;
00405   }
00406                 
00408   template<class T>
00409   inline const T* Array<T>::Iterator::operator-> () const
00410   {
00411         return p;
00412   }
00413 
00416 } // end namespace Dune
00417 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)