![]() |
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.