MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
array.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.googlecode.com.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_ARRAY
13 #define MFEM_ARRAY
14 
15 #include "../config/config.hpp"
16 #include "error.hpp"
17 
18 #include <iostream>
19 #include <cstdlib>
20 #include <cstring>
21 
22 namespace mfem
23 {
24 
26 class BaseArray
27 {
28 protected:
30  void *data;
32  int size;
34  int allocsize;
37  int inc;
38 
39  BaseArray() { }
41  BaseArray(int asize, int ainc, int elmentsize);
43  ~BaseArray();
47  void GrowSize(int minsize, int elementsize);
48 };
49 
50 template <class T>
51 class Array;
52 
53 template <class T>
54 void Swap(Array<T> &, Array<T> &);
55 
64 template <class T>
65 class Array : public BaseArray
66 {
67 public:
68  friend void Swap<T>(Array<T> &, Array<T> &);
69 
71  explicit inline Array(int asize = 0, int ainc = 0)
72  : BaseArray(asize, ainc, sizeof (T)) { }
73 
77  inline Array(T *_data, int asize, int ainc = 0)
78  { data = _data; size = asize; allocsize = -asize; inc = ainc; }
79 
81  inline ~Array() { }
82 
84  inline operator T *() { return (T *)data; }
85 
87  inline operator const T *() const { return (const T *)data; }
88 
90  inline T *GetData() { return (T *)data; }
92  inline const T *GetData() const { return (T *)data; }
93 
95  inline bool OwnsData() const { return (allocsize > 0); }
96 
98  inline void StealData(T **p)
99  { *p = (T*)data; data = 0; size = allocsize = 0; }
100 
102  inline void LoseData() { data = 0; size = allocsize = 0; }
103 
105  void MakeDataOwner() { allocsize = abs(allocsize); }
106 
108  inline int Size() const { return size; }
109 
112  inline int Capacity() const { return abs(allocsize); }
113 
115  inline void SetSize(int nsize);
116 
118  inline void SetSize(int nsize, const T &initval);
119 
121  inline T & operator[](int i);
122 
124  inline const T &operator[](int i) const;
125 
127  inline int Append(const T & el);
128 
130  inline int Append(const Array<T> &els);
131 
133  inline int Prepend(const T &el);
134 
136  inline T &Last();
137  inline const T &Last() const;
138 
140  inline int Union(const T & el);
141 
143  inline int Find(const T &el) const;
144 
146  inline void DeleteLast() { if (size > 0) size--; }
147 
149  inline void DeleteFirst(const T &el);
150 
152  inline void DeleteAll();
153 
155  inline void Copy(Array &copy) const
156  {
157  copy.SetSize(Size());
158  memcpy(copy.GetData(), data, Size()*sizeof(T));
159  }
160 
162  inline void MakeRef(T *, int);
163 
165  inline void MakeRef(const Array &master);
166 
167  inline void GetSubArray(int offset, int sa_size, Array<T> &sa);
168 
170  void Print(std::ostream &out, int width);
171 
173  void Save(std::ostream &out);
174 
177  T Max() const;
178 
181  T Min() const;
182 
184  void Sort();
185 
187  int IsSorted();
188 
190  void PartialSum();
191 
193  T Sum();
194 
195  inline void operator=(const T &a);
196 
198  inline void Assign(const T *);
199 
200 private:
204  Array(const Array<T> &);
205 };
206 
207 template <class T>
208 class Array2D;
209 
210 template <class T>
211 void Swap(Array2D<T> &, Array2D<T> &);
212 
213 template <class T>
214 class Array2D
215 {
216 private:
217  friend void Swap<T>(Array2D<T> &, Array2D<T> &);
218 
219  Array<T> array1d;
220  int N;
221 
222 public:
223  Array2D() { N = 0; }
224  Array2D(int m, int n) : array1d(m*n) { N = n; }
225 
226  void SetSize(int m, int n) { array1d.SetSize(m*n); N = n; }
227 
228  int NumRows() const { return array1d.Size()/N; }
229  int NumCols() const { return N; }
230 
231  inline const T &operator()(int i, int j) const;
232  inline T &operator()(int i, int j);
233 
234  inline const T *operator[](int i) const;
235  inline T *operator[](int i);
236 
237  const T *operator()(int i) const { return (*this)[i]; }
238  T *operator()(int i) { return (*this)[i]; }
239 
240  const T *GetRow(int i) const { return (*this)[i]; }
241  T *GetRow(int i) { return (*this)[i]; }
242 
243  void Copy(Array2D &copy) const
244  { copy.N = N; array1d.Copy(copy.array1d); }
245 
246  inline void operator=(const T &a)
247  { array1d = a; }
248 
250  inline void MakeRef(const Array2D &master)
251  { N = master.N; array1d.MakeRef(master.array1d);}
252 };
253 
254 
255 template <class T>
256 class Array3D
257 {
258 private:
259  Array<T> array1d;
260  int N2, N3;
261 
262 public:
263  Array3D() { N2 = N3 = 0; }
264  Array3D(int n1, int n2, int n3)
265  : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
266 
267  void SetSize(int n1, int n2, int n3)
268  { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
269 
270  inline const T &operator()(int i, int j, int k) const;
271  inline T &operator()(int i, int j, int k);
272 };
273 
274 
275 template <class T>
276 inline void Swap(T &a, T &b)
277 {
278  T c = a;
279  a = b;
280  b = c;
281 }
282 
283 template <class T>
284 inline void Swap(Array<T> &a, Array<T> &b)
285 {
286  Swap(a.data, b.data);
287  Swap(a.size, b.size);
288  Swap(a.allocsize, b.allocsize);
289  Swap(a.inc, b.inc);
290 }
291 
292 template <class T>
293 inline void Array<T>::SetSize(int nsize)
294 {
295  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
296  if (nsize > abs(allocsize))
297  GrowSize(nsize, sizeof(T));
298  size = nsize;
299 }
300 
301 template <class T>
302 inline void Array<T>::SetSize(int nsize, const T &initval)
303 {
304  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
305  if (nsize > size)
306  {
307  if (nsize > abs(allocsize))
308  GrowSize(nsize, sizeof(T));
309  for (int i = size; i < nsize; i++)
310  ((T*)data)[i] = initval;
311  }
312  size = nsize;
313 }
314 
315 template <class T>
316 inline T &Array<T>::operator[](int i)
317 {
318  MFEM_ASSERT( i>=0 && i<size, "Access element " << i << " of array, size = " << size );
319  return ((T*)data)[i];
320 }
321 
322 template <class T>
323 inline const T &Array<T>::operator[](int i) const
324 {
325  MFEM_ASSERT( i>=0 && i<size, "Access element " << i << " of array, size = " << size );
326  return ((T*)data)[i];
327 }
328 
329 template <class T>
330 inline int Array<T>::Append(const T &el)
331 {
332  SetSize(size+1);
333  ((T*)data)[size-1] = el;
334  return size;
335 }
336 
337 template <class T>
338 inline int Array<T>::Append(const Array<T> & els)
339 {
340  int old_size = size;
341 
342  SetSize(size + els.Size());
343  for (int i = 0; i < els.Size(); i++)
344  ((T*)data)[old_size+i] = els[i];
345  return size;
346 }
347 
348 
349 template <class T>
350 inline int Array<T>::Prepend(const T &el)
351 {
352  SetSize(size+1);
353  for (int i = size-1; i > 0; i--)
354  ((T*)data)[i] = ((T*)data)[i-1];
355  ((T*)data)[0] = el;
356  return size;
357 }
358 
359 
360 template <class T>
361 inline T &Array<T>::Last()
362 {
363  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
364  return ((T*)data)[size-1];
365 }
366 
367 template <class T>
368 inline const T &Array<T>::Last() const
369 {
370  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
371  return ((T*)data)[size-1];
372 }
373 
374 template <class T>
375 inline int Array<T>::Union(const T &el)
376 {
377  int i = 0;
378  while ((i < size) && (((T*)data)[i] != el)) i++;
379  if (i == size)
380  Append(el);
381  return i;
382 }
383 
384 template <class T>
385 inline int Array<T>::Find(const T &el) const
386 {
387  for (int i = 0; i < size; i++)
388  if (((T*)data)[i] == el)
389  return i;
390  return -1;
391 }
392 
393 template <class T>
394 inline void Array<T>::DeleteFirst(const T &el)
395 {
396  for (int i = 0; i < size; i++)
397  if (((T*)data)[i] == el)
398  {
399  for (i++; i < size; i++)
400  ((T*)data)[i-1] = ((T*)data)[i];
401  size--;
402  return;
403  }
404 }
405 
406 template <class T>
407 inline void Array<T>::DeleteAll()
408 {
409  if (allocsize > 0)
410  delete [] (char*)data;
411  data = NULL;
412  size = allocsize = 0;
413 }
414 
415 template <class T>
416 inline void Array<T>::MakeRef(T *p, int s)
417 {
418  if (allocsize > 0)
419  delete [] (char*)data;
420  data = p;
421  size = s;
422  allocsize = -s;
423 }
424 
425 template <class T>
426 inline void Array<T>::MakeRef(const Array &master)
427 {
428  if (allocsize > 0)
429  delete [] (char*)data;
430  data = master.data;
431  size = master.size;
432  allocsize = -abs(master.allocsize);
433  inc = master.inc;
434 }
435 
436 template <class T>
437 inline void Array<T>::GetSubArray(int offset, int sa_size, Array<T> &sa)
438 {
439  sa.SetSize(sa_size);
440  for (int i = 0; i < sa_size; i++)
441  sa[i] = (*this)[offset+i];
442 }
443 
444 template <class T>
445 inline void Array<T>::operator=(const T &a)
446 {
447  for (int i = 0; i < size; i++)
448  ((T*)data)[i] = a;
449 }
450 
451 template <class T>
452 inline void Array<T>::Assign(const T *p)
453 {
454  memcpy(data, p, Size()*sizeof(T));
455 }
456 
457 
458 template <class T>
459 inline const T &Array2D<T>::operator()(int i, int j) const
460 {
461  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
462  "Array2D: invalid access of element (" << i << ',' << j
463  << ") in array of size (" << array1d.Size()/N << ',' << N
464  << ")." );
465  return array1d[i*N+j];
466 }
467 
468 template <class T>
469 inline T &Array2D<T>::operator()(int i, int j)
470 {
471  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
472  "Array2D: invalid access of element (" << i << ',' << j
473  << ") in array of size (" << array1d.Size()/N << ',' << N
474  << ")." );
475  return array1d[i*N+j];
476 }
477 
478 template <class T>
479 inline const T *Array2D<T>::operator[](int i) const
480 {
481  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
482  "Array2D: invalid access of row " << i << " in array with "
483  << array1d.Size()/N << " rows.");
484  return &array1d[i*N];
485 }
486 
487 template <class T>
488 inline T *Array2D<T>::operator[](int i)
489 {
490  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
491  "Array2D: invalid access of row " << i << " in array with "
492  << array1d.Size()/N << " rows.");
493  return &array1d[i*N];
494 }
495 
496 
497 template <class T>
498 inline void Swap(Array2D<T> &a, Array2D<T> &b)
499 {
500  Swap(a.array1d, b.array1d);
501  Swap(a.N, b.N);
502 }
503 
504 
505 template <class T>
506 inline const T &Array3D<T>::operator()(int i, int j, int k) const
507 {
508  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
509  && k >= 0 && k < N3,
510  "Array3D: invalid access of element ("
511  << i << ',' << j << ',' << k << ") in array of size ("
512  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
513  return array1d[(i*N2+j)*N3+k];
514 }
515 
516 template <class T>
517 inline T &Array3D<T>::operator()(int i, int j, int k)
518 {
519  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
520  && k >= 0 && k < N3,
521  "Array3D: invalid access of element ("
522  << i << ',' << j << ',' << k << ") in array of size ("
523  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
524  return array1d[(i*N2+j)*N3+k];
525 }
526 
527 }
528 
529 #endif
int Size() const
Logical size of the array.
Definition: array.hpp:108
int NumCols() const
Definition: array.hpp:229
~BaseArray()
Free the allocated memory.
Definition: array.cpp:35
const T * operator()(int i) const
Definition: array.hpp:237
void * data
Pointer to data.
Definition: array.hpp:30
Array(T *_data, int asize, int ainc=0)
Definition: array.hpp:77
T * GetRow(int i)
Definition: array.hpp:241
Base class for array container.
Definition: array.hpp:26
void Copy(Array &copy) const
Create a copy of the current array.
Definition: array.hpp:155
T * GetData()
Returns the data.
Definition: array.hpp:90
T * operator()(int i)
Definition: array.hpp:238
void operator=(const T &a)
Definition: array.hpp:246
void operator=(const T &a)
Definition: array.hpp:445
T Sum()
Sum all entries.
Definition: array.cpp:132
void MakeRef(const Array2D &master)
Make this Array a reference to &#39;master&#39;.
Definition: array.hpp:250
void DeleteFirst(const T &el)
Delete the first &#39;el&#39; entry.
Definition: array.hpp:394
void SetSize(int n1, int n2, int n3)
Definition: array.hpp:267
T Min() const
Definition: array.cpp:91
void DeleteAll()
Delete whole array.
Definition: array.hpp:407
void GrowSize(int minsize, int elementsize)
Definition: array.cpp:41
~Array()
Destructor.
Definition: array.hpp:81
void GetSubArray(int offset, int sa_size, Array< T > &sa)
Definition: array.hpp:437
int size
Size of the array.
Definition: array.hpp:32
void SetSize(int m, int n)
Definition: array.hpp:226
void Copy(Array2D &copy) const
Definition: array.hpp:243
bool OwnsData() const
Return true if the data will be deleted by the array.
Definition: array.hpp:95
const T & operator()(int i, int j) const
Definition: array.hpp:459
const T * GetData() const
Returns the data.
Definition: array.hpp:92
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:330
T & operator[](int i)
Access element.
Definition: array.hpp:316
void LoseData()
NULL-ifies the data.
Definition: array.hpp:102
T Max() const
Definition: array.cpp:78
void Print(std::ostream &out, int width)
Prints array to stream with width elements per row.
Definition: array.cpp:57
void MakeDataOwner()
Make the Array own the data.
Definition: array.hpp:105
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
Definition: array.hpp:452
void Sort()
Sorts the array.
Definition: array.cpp:112
int allocsize
Size of the allocated memory.
Definition: array.hpp:34
void StealData(T **p)
Changes the ownership of the the data.
Definition: array.hpp:98
int Union(const T &el)
Append element when it is not yet in the array, return index.
Definition: array.hpp:375
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:284
int IsSorted()
return true if the array is sorted.
Definition: array.cpp:142
int Find(const T &el) const
Return the first index where &#39;el&#39; is found; return -1 if not found.
Definition: array.hpp:385
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:293
const T * operator[](int i) const
Definition: array.hpp:479
void PartialSum()
Partial Sum.
Definition: array.cpp:120
void Save(std::ostream &out)
Prints array to stream out.
Definition: array.cpp:70
void DeleteLast()
Delete the last entry.
Definition: array.hpp:146
Array2D(int m, int n)
Definition: array.hpp:224
int Capacity() const
Definition: array.hpp:112
T & Last()
Return the last element in the array.
Definition: array.hpp:361
void MakeRef(T *, int)
Make this Array a reference to a poiter.
Definition: array.hpp:416
const T & operator()(int i, int j, int k) const
Definition: array.hpp:506
Array3D(int n1, int n2, int n3)
Definition: array.hpp:264
Array(int asize=0, int ainc=0)
Creates array of asize elements.
Definition: array.hpp:71
const T * GetRow(int i) const
Definition: array.hpp:240
int NumRows() const
Definition: array.hpp:228
int Prepend(const T &el)
Prepend an element to the array, resize if necessary.
Definition: array.hpp:350