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;
00030
00031 public:
00033 Iterator();
00034
00036 bool operator!= (const Iterator& x);
00037
00039 bool operator== (const Iterator& x);
00040
00042 Iterator operator++ ();
00043
00045 Iterator operator++ (int);
00046
00048 const T& operator* () const;
00049
00051 const T* operator-> () const;
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> ©)
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;
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;
00175 T *p;
00176 } ;
00177
00178
00180 template<class T>
00181 inline typename Array<T>::Iterator Array<T>::begin () const
00182 {
00183 Iterator tmp;
00184 tmp.p = p;
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]);
00194 return tmp;
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
00261
00262
00263 template <class T>
00264 inline Array<T>::Array (const Array<T>& a)
00265 {
00266
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
00279 for (int i=0; i<n; i=i+1) p[i]=a.p[i];
00280 }
00281
00282
00283
00284 template <class T>
00285 inline Array<T>& Array<T>::operator= (const Array<T>& a)
00286 {
00287 if (&a!=this)
00288 {
00289 if (n!=a.n)
00290 {
00291
00292 if (n>0) delete[] p;
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;
00307 }
00308
00309
00310
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;
00317 }
00318
00319
00320
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
00330
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
00341
00342 template <class T>
00343 inline int Array<T>::size () const
00344 {
00345 return n;
00346 }
00347
00348
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;
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++ ()
00386 {
00387 p++;
00388 return *this;
00389 }
00390
00392 template<class T>
00393 inline typename Array<T>::Iterator Array<T>::Iterator::operator++ (int)
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 }
00417 #endif